<template>
  <div class="visualizer-container" :class="{ 'lyrics-mode': enableLyrics }">
    <img 
      v-if="currentImage" 
      :src="currentImage" 
      class="background-image"
      :class="{
        'red-filter-fading-in': redOverlayState === 'fading-in',
        'red-filter-visible': redOverlayState === 'visible',
        'red-filter-fading-out': redOverlayState === 'fading-out'
      }"
    />
    <button 
      class="add-button"
      @click="showAddMusic = !showAddMusic"
    >
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 16 16">
        <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
      </svg>
    </button>
    <button 
      class="settings-button"
      @click="showSettings = !showSettings"
    >
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 16 16">
        <path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z"/>
        <path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115l.094-.319z"/>
      </svg>
    </button>
    
    <!-- 波形，添加过渡效果 -->
    <transition name="fade">
      <div class="waveform-wrapper" v-if="!enableLyrics">
        <div class="waveform-container left">
          <div 
            v-for="(value, index) in waveformData" 
            :key="'left-' + index"
            class="waveform-bar"
            :style="{
              height: `${value}px`,
              animationDuration: `${1 / (gradientSpeed + 0.1)}s`,
              background: `linear-gradient(to top, 
                hsla(${colorHue}, 100%, 50%, 0.8),
                hsla(${colorHue}, 100%, 50%, 0.2)
              )`
            }"
          ></div>
        </div>
        <div class="waveform-container right">
          <div 
            v-for="(value, index) in waveformData" 
            :key="'right-' + index"
            class="waveform-bar"
            :style="{
              height: `${value}px`,
              animationDuration: `${1 / (gradientSpeed + 0.1)}s`,
              background: `linear-gradient(to top, 
                hsla(${colorHue}, 100%, 50%, 0.8),
                hsla(${colorHue}, 100%, 50%, 0.2)
              )`
            }"
          ></div>
        </div>
      </div>
    </transition>
    
    <!-- 标准布局（非歌词模式），添加过渡效果 -->
    <transition name="mode-fade">
      <div class="standard-layout" v-if="!enableLyrics">
        <div 
          class="cover-container" 
          @click="togglePlay"
          :style="{ transform: `scale(${1 + Math.pow(audioData, 3) * 1.0})` }"
        >
          <div class="progress-ring" @click.stop="togglePlay">
            <svg class="progress-ring__circle" width="220" height="220">
              <circle
                class="progress-ring__circle-bg"
                stroke-width="4"
                fill="transparent"
                r="108"
                cx="110"
                cy="110"
              />
              <circle
                class="progress-ring__circle-progress"
                stroke-width="4"
                fill="transparent"
                r="108"
                cx="110"
                cy="110"
                :style="{
                  strokeDasharray: `${progress * 6.79}, 679`,
                  stroke: `hsla(${colorHue}, 100%, 50%, 0.8)`
                }"
              />
            </svg>
          </div>
          <img 
            :src="currentImage" 
            class="visualizer-image" 
            :class="{ 'playing': isPlaying }"
          />
        </div>
        
        <div class="track-info" v-if="showTrackInfo && currentTrackIndex !== -1">
          <div class="track-title" 
            :class="{ 
              'playing': isPlaying, 
              'scroll-text': shouldScrollTitleNew 
            }"
            :style="{ color: textColorAdaptive }"
          >
            <div class="scroll-text-inner">{{ splitFileName(currentTrackInfo.title || currentTrackInfo.fileName).main }}</div>
          </div>
          <div class="track-prefix" v-if="splitFileName(currentTrackInfo.title || currentTrackInfo.fileName).prefix" :style="{ color: textColorSecondaryAdaptive }">
            {{ splitFileName(currentTrackInfo.title || currentTrackInfo.fileName).prefix }}
          </div>
          <div class="track-artist" v-if="currentTrackInfo.artist" :style="{ color: textColorSecondaryAdaptive }">
            {{ currentTrackInfo.artist }}
          </div>
        </div>
      </div>
    </transition>
    
    <!-- 歌词模式布局，添加过渡效果 -->
    <transition name="mode-slide">
      <div class="lyrics-layout" v-if="enableLyrics">
        <!-- 左侧专辑封面 -->
        <div class="lyrics-layout-left">
          <div 
            class="cover-container-lyrics" 
            @click="togglePlay"
            :style="{ transform: `scale(${1 + Math.pow(audioData, 3) * 0.5})` }"
          >
            <div class="progress-ring" @click.stop="togglePlay">
              <svg class="progress-ring__circle" width="180" height="180">
                <circle
                  class="progress-ring__circle-bg"
                  stroke-width="4"
                  fill="transparent"
                  r="88"
                  cx="90"
                  cy="90"
                />
                <circle
                  class="progress-ring__circle-progress"
                  stroke-width="4"
                  fill="transparent"
                  r="88"
                  cx="90"
                  cy="90"
                  :style="{
                    strokeDasharray: `${progress * 5.53}, 553`,
                    stroke: `hsla(${colorHue}, 100%, 50%, 0.8)`
                  }"
                />
              </svg>
            </div>
            <img 
              :src="currentImage" 
              class="visualizer-image" 
              :class="{ 'playing': isPlaying }"
            />
          </div>
        </div>
        
        <!-- 右侧内容 -->
        <div class="lyrics-layout-right">
          <!-- 标题/艺术家 -->
          <div class="lyrics-track-info" v-if="showTrackInfo && currentTrackIndex !== -1">
            <div class="track-title" :style="{ color: textColorAdaptive }">
              {{ splitFileName(currentTrackInfo.title || currentTrackInfo.fileName).main }}
            </div>
            <div class="track-prefix" v-if="splitFileName(currentTrackInfo.title || currentTrackInfo.fileName).prefix" :style="{ color: textColorSecondaryAdaptive }">
              {{ splitFileName(currentTrackInfo.title || currentTrackInfo.fileName).prefix }}
            </div>
            <div class="track-artist" v-if="currentTrackInfo.artist" :style="{ color: textColorSecondaryAdaptive }">
              {{ currentTrackInfo.artist }}
            </div>
          </div>
          
          <!-- 歌词容器 -->
          <div class="lyrics-container-integrated" v-if="currentLyrics.length > 0" ref="lyricsContainer">
            <div class="lyrics-debug" v-if="showLyricsDebug">
              <div>Lyrics Enabled: {{ enableLyrics }}</div>
              <div>Total Lines: {{ currentLyrics.length }}</div>
              <div>Current Index: {{ currentLyricIndex }}</div>
            </div>
            <div class="lyrics-wrapper">
              <div class="lyrics-content" ref="lyricsContent">
                <div 
                  v-for="(line, index) in currentLyrics" 
                  :key="index"
                  class="lyric-line"
                  :class="{ 'active': currentLyricIndex === index }"
                  :id="`lyric-${index}`"
                  :style="{ color: currentLyricIndex === index ? textColorAdaptive : textColorSecondaryAdaptive }"
                >
                  {{ line.text }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </transition>
    
    <!-- 独立歌词容器，在非歌词模式下使用 -->
    <div class="lyrics-container" v-if="enableLyrics && !currentLyrics.length && !enableLyrics" ref="lyricsContainer">
      <div class="lyrics-debug" v-if="showLyricsDebug">
        <div>Lyrics Enabled: {{ enableLyrics }}</div>
        <div>Total Lines: {{ currentLyrics.length }}</div>
        <div>Current Index: {{ currentLyricIndex }}</div>
      </div>
      <div class="lyrics-wrapper">
        <div class="lyrics-content" ref="lyricsContent">
          <div 
            v-for="(line, index) in currentLyrics" 
            :key="index"
            class="lyric-line"
            :class="{ 'active': currentLyricIndex === index }"
            :id="`lyric-${index}`"
            :style="{ color: currentLyricIndex === index ? textColorAdaptive : textColorSecondaryAdaptive }"
          >
            {{ line.text }}
          </div>
        </div>
      </div>
    </div>
    
    <div class="settings-modal" v-if="showAddMusic">
      <div class="settings-content">
        <div class="settings-header">
          <h3>添加音乐</h3>
          <button class="close-button" @click="showAddMusic = false">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
              <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
            </svg>
          </button>
        </div>
        <div class="settings-columns">
          <div class="settings-column settings-left">
            <div class="mb-3">
              <label class="form-label">选择音乐文件</label>
              <input 
                type="file" 
                accept="audio/*" 
                @change="handleFileChange" 
                class="form-control"
                multiple
              />
            </div>
            <div class="mb-3">
              <label class="form-label">选择音乐文件夹</label>
              <input 
                type="file" 
                @change="handleFolderChange" 
                class="form-control"
                webkitdirectory
                directory
                multiple
              />
            </div>
            <div class="mb-3">
              <label class="form-label">添加网易云音乐</label>
              <div class="netease-input-group">
                <input 
                  type="text" 
                  v-model="neteaseLink" 
                  class="form-control" 
                  placeholder="粘贴网易云音乐分享链接"
                />
                <button 
                  class="btn btn-primary netease-add-btn" 
                  @click="addNeteaseSong"
                >
                  添加
                </button>
              </div>
              <small class="form-text text-muted">支持网易云音乐各种格式链接（使用byfuns API）</small>
            </div>
            <div class="mb-3">
              <label class="form-label">通过歌单JSON导入</label>
              <div class="netease-input-group mb-2">
                <input 
                  type="file" 
                  accept="application/json" 
                  @change="handlePlaylistJsonUpload" 
                  class="form-control"
                />
              </div>
              <div class="netease-input-group">
                <button 
                  class="btn btn-secondary netease-help-btn" 
                  @click="getPlaylistJsonHelp"
                >
                  获取歌单JSON
                </button>
              </div>
              <small class="form-text text-muted">上传网易云音乐歌单API返回的JSON文件，或点击获取按钮生成下载链接</small>
            </div>
            <div class="mb-3">
              <label class="form-label">添加网易云音乐歌单</label>
              <div class="netease-input-group">
                <input 
                  type="text" 
                  v-model="neteasePlaylistLink" 
                  class="form-control" 
                  placeholder="粘贴网易云音乐歌单分享链接"
                />
                <button 
                  class="btn btn-primary netease-add-btn" 
                  @click="addNeteasePlaylist"
                  :disabled="isLoading"
                >
                  导入歌单
                </button>
              </div>
              <small class="form-text text-muted">一键导入整个歌单（VIP歌曲可能无法播放）</small>
            </div>
            <div class="mb-3">
              <label class="form-label">添加外部音乐</label>
              <div class="external-input-group">
                <input 
                  type="text" 
                  v-model="externalMusicUrl" 
                  class="form-control mb-2" 
                  placeholder="直接输入音乐URL"
                />
                <input 
                  type="text" 
                  v-model="externalMusicTitle" 
                  class="form-control mb-2" 
                  placeholder="歌曲名称"
                />
                <input 
                  type="text" 
                  v-model="externalMusicArtist" 
                  class="form-control mb-2" 
                  placeholder="艺术家名称 (可选)"
                />
                <button 
                  class="btn btn-primary external-add-btn" 
                  @click="addExternalMusic"
                >
                  添加外部音乐
                </button>
              </div>
              <small class="form-text text-muted">添加任意可直接访问的音乐URL</small>
            </div>
          </div>
          <div class="settings-divider"></div>
          <div class="settings-column settings-right">
            <h4>播放列表</h4>
            
            <!-- 导入进度显示，仅在播放列表页时显示 -->
            <div class="playlist-import-status" v-if="backgroundImport.active">
              <div class="bg-import-content">
                <div class="bg-import-header">
                  <span>正在导入歌单</span>
                  <button class="bg-import-cancel" @click="cancelBackgroundImport">取消</button>
                </div>
                <div class="bg-import-progress">
                  <div class="bg-import-progress-bar" :style="{width: `${backgroundImport.progress}%`}"></div>
                </div>
                <div class="bg-import-stats">
                  已导入: {{ backgroundImport.completed }}/{{ backgroundImport.total }} 
                  <span v-if="backgroundImport.failed > 0" class="bg-import-failed">
                    (失败: {{ backgroundImport.failed }})
                  </span>
                </div>
                <div class="bg-import-current">当前: {{ backgroundImport.currentTrack }}</div>
              </div>
            </div>
            
            <div class="playlist-header">
              <div class="playlist-header-title">歌曲列表</div>
              <div class="playlist-header-hint">拖动歌曲可调整顺序</div>
            </div>
            <div class="playlist-items" v-if="playlist.length > 0" ref="playlistRef">
              <div 
                v-for="(track, index) in playlist" 
                :key="index"
                class="playlist-item"
                :class="{ 'active': index === currentTrackIndex }"
                @click="loadTrack(index)"
                :data-index="index"
              >
                <div class="playlist-item-drag-handle">
                  <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
                    <path d="M7 2a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm-3 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0zm3 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
                  </svg>
                </div>
                <div class="playlist-item-info">
                  <div class="playlist-item-main">{{ splitFileName(track.title || track.name).main }}</div>
                  <div class="playlist-item-prefix">{{ splitFileName(track.title || track.name).prefix }}</div>
                </div>
                <button 
                  class="playlist-item-remove" 
                  @click.stop="removeFromPlaylist(index)"
                  title="从播放列表移除"
                >
                  <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
                    <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
                  </svg>
                </button>
              </div>
            </div>
            <div class="no-playlist" v-else>
              <p>播放列表为空，请添加音乐文件</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="settings-modal" v-if="showSettings">
      <div class="settings-content">
        <div class="settings-header">
          <h3>设置</h3>
          <button class="close-button" @click="showSettings = false">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
              <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
            </svg>
          </button>
        </div>
        <div class="settings-body">
          <div class="mb-3">
            <label class="form-label">选择背景图片（可选）</label>
            <input 
              type="file" 
              accept="image/*" 
              @change="handleImageChange" 
              class="form-control"
            />
          </div>
          <div class="mb-3">
            <label class="form-label">快退/进时间（秒）</label>
            <input 
              type="number" 
              v-model="seekTime" 
              class="form-control" 
              min="1" 
              max="60"
            />
          </div>
          <div class="mb-3">
            <label class="form-label">全屏模式下鼠标隐藏时间（秒）</label>
            <input 
              type="number" 
              v-model="autoHideCursorDelay" 
              class="form-control" 
              min="0" 
              max="10"
              step="0.5"
            />
            <small class="form-text text-muted">设置为0表示不自动隐藏鼠标</small>
          </div>
          <div class="mb-3">
            <label class="form-label">播放模式</label>
            <select v-model="playbackMode" class="form-control">
              <option value="list-loop">列表循环</option>
              <option value="single-loop">单曲循环</option>
              <option value="list-once">列表播放完暂停</option>
              <option value="single-once">单曲播放完暂停</option>
            </select>
          </div>
          
          <!-- 播放列表管理功能 -->
          <div class="settings-section">
            <h5 class="settings-section-title">播放列表管理</h5>
            <div class="btn-group w-100 mb-3">
              <button class="btn btn-primary" @click="exportPlaylist">
                导出播放列表
              </button>
              <button class="btn btn-secondary" @click="showAddMusic = true; showSettings = false;">
                管理播放列表
              </button>
            </div>
            <small class="form-text text-muted">导出的播放列表可以在下次使用时通过JSON导入功能重新加载</small>
          </div>
          
          <div class="mb-3 form-check">
            <input 
              type="checkbox" 
              id="showKeyboardTips" 
              v-model="showKeyboardTips" 
              class="form-check-input"
            />
            <label class="form-check-label" for="showKeyboardTips">
              显示键盘快捷键提示
            </label>
          </div>
          <div class="mb-3 form-check">
            <input 
              type="checkbox" 
              id="showTrackInfo" 
              v-model="showTrackInfo" 
              class="form-check-input"
            />
            <label class="form-check-label" for="showTrackInfo">
              显示歌曲信息
            </label>
          </div>
          <div class="mb-3 form-check">
            <input 
              type="checkbox" 
              id="isFullscreen" 
              v-model="isFullscreen" 
              class="form-check-input"
              @change="toggleFullscreen"
            />
            <label class="form-check-label" for="isFullscreen">
              全屏模式（按ESC退出）
            </label>
          </div>
          <div class="mb-3 form-check">
            <input 
              type="checkbox" 
              id="enableRedEffect" 
              v-model="enableRedEffect" 
              class="form-check-input"
            />
            <label class="form-check-label" for="enableRedEffect">
              激情红温（音乐激烈时自动添加红色氛围）
            </label>
          </div>
          <div class="mb-3 form-check">
            <input 
              type="checkbox" 
              id="enableLyrics" 
              v-model="enableLyrics" 
              class="form-check-input"
            />
            <label class="form-check-label" for="enableLyrics">
              启用歌词显示
            </label>
          </div>
          <div class="mb-3" v-if="enableLyrics">
            <label class="form-label">导入LRC歌词文件（可选）</label>
            <input 
              type="file" 
              accept=".lrc" 
              @change="handleLrcChange" 
              class="form-control"
            />
            <small class="form-text text-muted">对于网易云音乐，歌词将自动获取（如可用）</small>
            <div class="mt-2">
              <label class="form-label">网易云音乐ID（可选）</label>
              <div class="input-group">
                <input 
                  type="text" 
                  v-model="neteaseMusicId" 
                  placeholder="输入网易云音乐ID" 
                  class="form-control"
                />
                <button 
                  class="btn btn-outline-secondary" 
                  type="button"
                  @click="fetchNeteaseLyricsManually"
                >
                  获取歌词
                </button>
              </div>
              <small class="form-text text-muted">输入ID后点击获取歌词，或在歌曲标题中包含[id:歌曲ID]自动获取</small>
            </div>
          </div>
        </div>
        <div class="settings-footer">
          <button class="btn btn-primary" @click="saveSettings">确定</button>
        </div>
      </div>
    </div>

    <div class="keyboard-tips" v-if="audioElement && showKeyboardTips">
      <div class="tip">
        <span class="key">空格</span> 播放/暂停
      </div>
      <div class="tip">
        <span class="key">←</span> 快退 {{seekTime}}秒
      </div>
      <div class="tip">
        <span class="key">→</span> 快进 {{seekTime}}秒
      </div>
      <div class="tip">
        <span class="key">↑</span> 上一曲
      </div>
      <div class="tip">
        <span class="key">↓</span> 下一曲
      </div>
      <div class="tip">
        <span class="key">H</span> 红温开关
      </div>
      <div class="tip">
        <span class="key">L</span> 歌词开关
      </div>
      <div class="tip">
        <span class="key">G</span> 提示开关
      </div>
      <div class="tip">
        <span class="key">F</span> 全屏
      </div>
    </div>

    <div class="empty-playlist-notice" v-if="showSettings && playlist.length === 0">
      <div class="notice-text">播放列表为空，请添加歌曲</div>
    </div>

    <!-- 加载提示 -->
    <div class="loading-overlay" v-if="isLoading">
      <div class="loading-spinner"></div>
      <div class="loading-message">{{ loadingMessage }}</div>
    </div>

    <!-- 通知系统 -->
    <transition name="notification-slide">
      <div v-if="notification.show" class="notification" :class="notification.type">
        <div class="notification-content">
          <div class="notification-message">{{ notification.message }}</div>
          <button class="notification-close" @click="closeNotification">
            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
              <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
            </svg>
          </button>
        </div>
      </div>
    </transition>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, computed, watch, nextTick } from 'vue'
import Sortable from 'sortablejs'

const audioContext = ref(null)
const analyser = ref(null)
const audioData = ref(0)
const isPlaying = ref(false)
const audioElement = ref(null)
const currentImage = ref('https://picsum.photos/200')
const defaultImage = 'https://picsum.photos/200'
const waveformData = ref(new Array(64).fill(0))
const gradientSpeed = ref(0)
const colorHue = ref(240)
const targetHue = ref(240)
const showSettings = ref(false)
const playlist = ref([])
const currentTrackIndex = ref(-1)
const progress = ref(0)
const seekTime = ref(10)
const showKeyboardTips = ref(true)
const showTrackInfo = ref(true)
const currentTrackInfo = ref({ title: '', artist: '' })
const isFullscreen = ref(false)
const autoHideCursorDelay = ref(2) // 默认2秒后隐藏鼠标
const enableRedEffect = ref(false) // 激情红温开关
const playbackMode = ref('list-loop') // 播放模式：'single-loop', 'list-loop', 'list-once', 'single-once'
const showRedOverlay = ref(false) // 控制红色蒙层显示
const redOverlayState = ref('hidden') // 红色蒙层状态: 'hidden', 'fading-in', 'visible', 'fading-out'
let redStateTime = 0 // 记录红色状态的持续时间
let lastRedCheckTime = 0 // 上次检查红色状态的时间
let redVisibleStartTime = 0 // 记录红色蒙层完全显示的开始时间
let redFadeInStartTime = 0 // 记录红色蒙层开始渐入的时间
const RED_MIN_VISIBLE_DURATION = 5000 // 红色蒙层最短显示时间(5秒)
const RED_FADE_DURATION = 5000 // 红色蒙层渐变时间(5秒)
let cursorTimeoutId = null // 存储鼠标隐藏定时器ID
let lastTime = 0
const neteaseLink = ref('')
const isLoading = ref(false)
const loadingMessage = ref('')
const proxyServerUrl = ref('https://www.byfuns.top/api/1') // 使用指定的API
const metadataApiUrl = ref('https://music.163.com/api/song/detail') // 歌曲元数据API
const externalMusicUrl = ref('')
const externalMusicTitle = ref('')
const externalMusicArtist = ref('')
const showAddMusic = ref(false)
const neteasePlaylistLink = ref('')

const notification = ref({
  show: false,
  message: '',
  type: 'info', // 'info', 'success', 'error'
  timeout: null
})

const backgroundImport = ref({
  active: false,
  total: 0,
  completed: 0,
  failed: 0,
  progress: 0,
  currentTrack: '',
  taskId: null
})

const updateVisualization = (timestamp) => {
  if (!analyser.value) return
  
  const dataArray = new Uint8Array(analyser.value.frequencyBinCount)
  analyser.value.getByteFrequencyData(dataArray)
  
  // 更新波形数据，增加幅度
  waveformData.value = Array.from(dataArray.slice(0, 64)).map(value => value * 1.5)
  
  // 使用低频部分的数据，这样跳动更明显
  const lowFrequencyData = dataArray.slice(0, 10)
  const average = lowFrequencyData.reduce((a, b) => a + b) / lowFrequencyData.length
  audioData.value = average / 255
  
  // 根据音频强度调整渐变速度
  gradientSpeed.value = Math.pow(audioData.value, 2) * 2

  // 计算目标色相
  targetHue.value = 240 - (audioData.value * 240)
  
  // 平滑过渡到目标色相
  const hueDiff = targetHue.value - colorHue.value
  colorHue.value += hueDiff * 0.1 // 使用较小的系数使变化更平滑

  // 计算时间差
  const deltaTime = timestamp - lastTime
  lastTime = timestamp
  
  // 激情红温功能：检测红色状态
  if (enableRedEffect.value && isPlaying.value) {
    // 检查是否处于红色状态（Hue < 30，接近红色）
    const isRedState = colorHue.value < 30
    
    // 计算自上次检查后的时间差
    const redCheckDelta = timestamp - lastRedCheckTime
    lastRedCheckTime = timestamp
    
    if (isRedState) {
      // 在红色状态下累加时间
      redStateTime += redCheckDelta
      
      // 如果累计超过3000毫秒（3秒），开始显示红色蒙层
      if (redStateTime >= 3000) {
        
        // 如果红色蒙层处于隐藏状态，开始渐入
        if (redOverlayState.value === 'hidden') {
          redOverlayState.value = 'fading-in'
          redFadeInStartTime = timestamp
          showRedOverlay.value = true
        }
        
        // 检查渐入是否完成
        if (redOverlayState.value === 'fading-in' && 
            timestamp - redFadeInStartTime >= RED_FADE_DURATION) {
          redOverlayState.value = 'visible'
          redVisibleStartTime = timestamp
        }
      }
    } else {
      // 不是红色状态，重置红色持续时间
      redStateTime = 0
      
      // 如果红色蒙层显示中，检查是否已经停留足够时间
      if (redOverlayState.value === 'visible') {
        const visibleDuration = timestamp - redVisibleStartTime
        
        // 只有在显示至少5秒后才开始渐出
        if (visibleDuration >= RED_MIN_VISIBLE_DURATION) {
          redOverlayState.value = 'fading-out'
          
          // 在渐出动画完成后重置状态
          setTimeout(() => {
            if (redOverlayState.value === 'fading-out') {
              redOverlayState.value = 'hidden'
              showRedOverlay.value = false
            }
          }, RED_FADE_DURATION)
        }
      }
    }
  } else {
    // 如果功能被禁用，重置所有状态
    if (redOverlayState.value !== 'hidden') {
      redOverlayState.value = 'hidden'
      showRedOverlay.value = false
      redStateTime = 0
    }
  }

  animationFrame = requestAnimationFrame(updateVisualization)
}

const createAudioContext = () => {
  try {
    // 检查浏览器兼容性
    audioContext.value = new (window.AudioContext || window.webkitAudioContext)()
    analyser.value = audioContext.value.createAnalyser()
    // 设置FFT大小，影响频谱的精度
    analyser.value.fftSize = 2048
    // 设置平滑常数，取值0-1，数值越大平滑效果越明显
    analyser.value.smoothingTimeConstant = 0.85
  } catch (e) {
    console.error('创建音频上下文失败:', e)
    showError('创建音频上下文失败: ' + e.message)
  }
}

const addToPlaylist = async (files) => {
  if (!files || files.length === 0) return
  
  const newTracks = await Promise.all(
    Array.from(files).map(async (file) => {
      if (!file.type.startsWith('audio/')) return null
      
      const track = {
        file,
        url: URL.createObjectURL(file),
        name: file.name,
        title: '',
        artist: ''
      }
      
      // 尝试获取ID3标签信息
      try {
        // 简单的方式获取音频元数据
        const audio = new Audio()
        audio.src = track.url
        await new Promise(resolve => {
          audio.addEventListener('loadedmetadata', resolve, { once: true })
          audio.addEventListener('error', resolve, { once: true })
        })
        
        if (audio.duration) {
          track.duration = audio.duration
          // 这里如果有更复杂的ID3标签处理，可以添加额外代码
        }
      } catch (e) {
        console.error('无法获取音频元数据', e)
      }
      
      return track
    })
  )
  
  // 过滤掉无效的文件
  const validTracks = newTracks.filter(track => track !== null)
  playlist.value = [...playlist.value, ...validTracks]
  
  // 如果当前没有播放的曲目，加载第一首
  if (currentTrackIndex.value === -1 && playlist.value.length > 0) {
    currentTrackIndex.value = 0
    await loadTrack(0)
  }
}

const removeFromPlaylist = async (index) => {
  // 如果删除的是当前播放的歌曲
  if (index === currentTrackIndex.value) {
    if (playlist.value.length === 1) {
      // 如果只有一首歌
      if (audioElement.value) {
        audioElement.value.pause()
        URL.revokeObjectURL(audioElement.value.src)
        audioElement.value = null
      }
      playlist.value = []
      currentTrackIndex.value = -1
      currentTrackInfo.value = { title: '', artist: '' }
    } else {
      // 切换到下一首，如果是最后一首则切换到第一首
      const nextIndex = index === playlist.value.length - 1 ? 0 : index
      playlist.value.splice(index, 1)
      currentTrackIndex.value = nextIndex === playlist.value.length ? 0 : nextIndex
      await loadTrack(currentTrackIndex.value)
    }
  } else {
    // 如果删除的不是当前播放的歌曲
    playlist.value.splice(index, 1)
    // 如果删除的是当前歌曲之前的歌曲，需要调整索引
    if (index < currentTrackIndex.value) {
      currentTrackIndex.value--
    }
  }
}

const handleFolderChange = async (event) => {
  const files = event.target.files
  await addToPlaylist(files)
}

const handleFileChange = async (event) => {
  const files = event.target.files
  await addToPlaylist(files)
}

const updateProgress = () => {
  if (audioElement.value) {
    progress.value = (audioElement.value.currentTime / audioElement.value.duration) * 100
  }
}

const loadTrack = async (index) => {
  if (index < 0 || index >= playlist.value.length) return
  
  // 首先更新当前曲目索引
  currentTrackIndex.value = index
  
  if (audioElement.value) {
    audioElement.value.pause()
    if (audioElement.value.src.startsWith('blob:')) {
      URL.revokeObjectURL(audioElement.value.src)
    }
  }
  
  const track = playlist.value[index]
  audioElement.value = new Audio()
  
  // 添加错误处理
  audioElement.value.addEventListener('error', async (e) => {
    console.error('音频加载错误:', e);
    
    // 检查是否为网易云音乐，如果是则尝试重新加载
    if (track.type === 'netease' && track.id) {
      showError(`加载音乐失败，正在尝试重新获取...`);
      const success = await reloadNeteaseSong(index);
      if (!success) {
        showError(`无法播放《${track.title}》，请尝试重新添加或使用其他音乐源`);
      }
    } else {
      showError(`无法播放音乐: ${e.target.error ? e.target.error.message : '未知错误'}`);
    }
  });
  
  try {
    // 确保音频上下文已创建
    if (!audioContext.value) {
      createAudioContext()
    }
    
    if (audioContext.value.state === 'suspended') {
      await audioContext.value.resume()
    }
    
    // 加载音频
    audioElement.value.crossOrigin = "anonymous"; // 添加跨域支持
    audioElement.value.src = track.url
    audioElement.value.loop = playbackMode.value === 'single-loop' // 只有单曲循环模式时设置循环
    
    console.log("加载音频URL:", track.url);
    
    // 设置播放结束事件处理
    audioElement.value.addEventListener('ended', handlePlaybackEnd)
    
    // 更新进度条
    audioElement.value.addEventListener('timeupdate', updateProgress)
    
    // 添加时间更新监听器用于歌词同步
    audioElement.value.addEventListener('timeupdate', audioTimeUpdate)
    
    // 更新当前歌曲信息
    currentTrackInfo.value = {
      title: track.title || '',
      artist: track.artist || '',
      fileName: track.name
    }
    
    // 使用歌曲专辑封面（如果有）或默认图片
    if (track.coverUrl) {
      currentImage.value = track.coverUrl;
      console.log("使用歌曲封面:", track.coverUrl);
    } else {
      console.log('无歌曲封面，使用默认图片');
      currentImage.value = defaultImage;
    }
    
    // 先断开之前的连接
    try {
      analyser.value.disconnect()
    } catch (e) {
      // 如果没有连接，会抛出错误，忽略
    }
    
    // 创建媒体元素源并连接
    const source = audioContext.value.createMediaElementSource(audioElement.value)
    source.connect(analyser.value)
    analyser.value.connect(audioContext.value.destination)
    
    // 预加载音频
    await new Promise((resolve) => {
      audioElement.value.addEventListener('canplaythrough', resolve, { once: true });
      audioElement.value.load();
    });
    
    // 更新当前播放的歌曲，获取歌词
    updateCurrentTrack();
    
    if (isPlaying.value) {
      try {
        // 播放前再次确认上下文已恢复
        if (audioContext.value.state === 'suspended') {
          await audioContext.value.resume();
        }
        
        const playPromise = audioElement.value.play();
        await playPromise; // 等待播放真正开始
        console.log("音频开始播放");
      } catch (e) {
        console.error('播放失败:', e)
        showError('播放失败: ' + e.message)
        isPlaying.value = false
      }
    }
  } catch (error) {
    console.error('加载曲目时出错:', error);
    showError('加载曲目失败: ' + error.message);
  }
}

const handlePlaybackEnd = () => {
  switch (playbackMode.value) {
    case 'single-loop':
      // 单曲循环：重新播放当前歌曲
      audioElement.value.currentTime = 0
      audioElement.value.play()
      break
    case 'list-loop':
      // 列表循环：播放下一首
      playNext()
      break
    case 'list-once':
      // 列表播放完暂停：如果不是最后一首，播放下一首
      if (currentTrackIndex.value < playlist.value.length - 1) {
        playNext()
      } else {
        isPlaying.value = false
      }
      break
    case 'single-once':
      // 单曲播放完暂停：不做任何处理，让它自然停止
      isPlaying.value = false
      break
  }
}

const playNext = async () => {
  const nextIndex = (currentTrackIndex.value + 1) % playlist.value.length
  await loadTrack(nextIndex)
}

const playPrevious = async () => {
  const prevIndex = (currentTrackIndex.value - 1 + playlist.value.length) % playlist.value.length
  await loadTrack(prevIndex)
}

const handleImageChange = (event) => {
  const file = event.target.files[0]
  if (file) {
    const url = URL.createObjectURL(file)
    currentImage.value = url
  }
}

const togglePlay = async () => {
  // 如果播放列表为空，显示添加音乐框
  if (playlist.value.length === 0) {
    showAddMusic.value = true
    // 在Vue的下一个渲染周期显示提示信息
    setTimeout(() => {
      showError('播放列表为空，请添加歌曲')
    }, 100)
    return
  }
  
  if (!audioElement.value) return
  
  if (isPlaying.value) {
    audioElement.value.pause()
    isPlaying.value = false
  } else {
    try {
      // 确保音频上下文已恢复
      if (audioContext.value && audioContext.value.state === 'suspended') {
        await audioContext.value.resume()
      }
      
      const playPromise = audioElement.value.play();
      await playPromise; // 等待播放真正开始
      console.log("通过点击开始播放");
      isPlaying.value = true
    } catch (error) {
      console.error('播放失败:', error)
      showError('播放失败: ' + error.message)
    }
  }
}

const saveSettings = () => {
  try {
    const settings = {
      enableRedEffect: enableRedEffect.value,
      enableLyrics: enableLyrics.value,
      // ... 其他设置
    };
    localStorage.setItem('musicVisualizerSettings', JSON.stringify(settings));
  } catch (e) {
    console.error('保存设置时出错:', e);
  }
  showSettings.value = false;
}

const handleKeyDown = (event) => {
  if (!audioElement.value) return
  
  // 防止在输入框中触发快捷键
  if (event.target.tagName === 'INPUT') return
  
  switch (event.key) {
    case 'ArrowLeft':
      // 快退
      audioElement.value.currentTime = Math.max(0, audioElement.value.currentTime - seekTime.value)
      break
    case 'ArrowRight':
      // 快进
      audioElement.value.currentTime = Math.min(audioElement.value.duration, audioElement.value.currentTime + seekTime.value)
      break
    case ' ':
      // 空格播放/暂停
      event.preventDefault() // 防止页面滚动
      togglePlay()
      break
    case 'ArrowUp':
      // 上键上一曲
      event.preventDefault() // 防止页面滚动
      playPrevious()
      break
    case 'ArrowDown':
      // 下键下一曲
      event.preventDefault() // 防止页面滚动
      playNext()
      break
    case '-':
      // 减号键上一曲
      playPrevious()
      break
    case '=': // 兼容无需按Shift的键盘
    case '+':
      // 加号键下一曲
      playNext()
      break
    case 'g':
    case 'G':
      // G键隐藏/显示键盘提示
      toggleKeyboardTips()
      break
    case 'f':
    case 'F':
      // F键切换全屏
      toggleFullscreen()
      break
    case 'h':
    case 'H':
      // H键切换红温模式
      toggleRedEffect()
      break
    case 'l':
    case 'L':
      // L键切换歌词模式
      enableLyrics.value = !enableLyrics.value
      break
  }
}

const toggleKeyboardTips = () => {
  showKeyboardTips.value = !showKeyboardTips.value
}

// 文件名分割函数：先去除扩展名，再寻找第一个-号，分割文件名
const splitFileName = (fileName) => {
  if (!fileName) return { prefix: '', main: '' }
  
  // 先移除扩展名
  const nameWithoutExt = fileName.replace(/\.(mp3|wav|ogg|flac|aac|m4a|wma|alac)$/i, '')
  
  // 寻找第一个-号
  const match = nameWithoutExt.match(/^(.*?)-(.*)$/)
  if (match) {
    return {
      prefix: match[1].trim(),
      main: match[2].trim()
    }
  }
  
  return {
    prefix: '',
    main: nameWithoutExt
  }
}

// 全屏方法
const toggleFullscreen = () => {
  if (!document.fullscreenElement) {
    document.documentElement.requestFullscreen().then(() => {
      isFullscreen.value = true
    }).catch(err => {
      console.error(`全屏请求被拒绝: ${err.message}`)
    })
  } else {
    if (document.exitFullscreen) {
      document.exitFullscreen().then(() => {
        isFullscreen.value = false
      }).catch(err => {
        console.error(`退出全屏出错: ${err.message}`)
      })
    }
  }
}

// 添加鼠标移动事件处理
const handleMouseMove = () => {
  // 如果不是全屏模式或延迟设置为0，不处理
  if (!isFullscreen.value || autoHideCursorDelay.value <= 0) {
    document.body.style.cursor = 'auto'
    return
  }
  
  // 显示鼠标
  document.body.style.cursor = 'auto'
  
  // 清除之前的定时器
  if (cursorTimeoutId) {
    clearTimeout(cursorTimeoutId)
  }
  
  // 设置新的定时器
  cursorTimeoutId = setTimeout(() => {
    if (isFullscreen.value) {
      document.body.style.cursor = 'none'
    }
  }, autoHideCursorDelay.value * 1000)
}

// 在全屏变化事件处理中添加鼠标隐藏逻辑
const handleFullscreenChange = () => {
  isFullscreen.value = !!document.fullscreenElement
  
  // 如果退出全屏，恢复鼠标显示
  if (!isFullscreen.value) {
    document.body.style.cursor = 'auto'
    if (cursorTimeoutId) {
      clearTimeout(cursorTimeoutId)
      cursorTimeoutId = null
    }
  } else if (autoHideCursorDelay.value > 0) {
    // 如果进入全屏且启用了自动隐藏，设置定时器
    handleMouseMove()
  }
}

// 切换红温模式
const toggleRedEffect = () => {
  enableRedEffect.value = !enableRedEffect.value
  // 如果关闭红温，立即清除当前的红色覆盖
  if (!enableRedEffect.value && redOverlayState.value !== 'hidden') {
    redOverlayState.value = 'hidden'
    showRedOverlay.value = false
    redStateTime = 0
  }
}

// 监听播放模式变化
watch(playbackMode, (newMode) => {
  if (audioElement.value) {
    // 只有单曲循环模式时设置循环
    audioElement.value.loop = newMode === 'single-loop'
  }
})

let animationFrame

const playlistRef = ref(null)
let sortableInstance = null

// 初始化Sortable.js
const initSortable = () => {
  if (!playlistRef.value) return
  
  // 确保之前的实例被销毁
  if (sortableInstance) {
    sortableInstance.destroy()
  }
  
  // 创建新的实例
  sortableInstance = Sortable.create(playlistRef.value, {
    handle: '.playlist-item-drag-handle',  // 指定拖动手柄元素
    animation: 150,  // 动画速度
    ghostClass: 'playlist-item-ghost',  // 拖动时的样式类
    chosenClass: 'playlist-item-chosen',  // 选中时的样式类
    dragClass: 'playlist-item-drag',  // 拖动中的样式类
    onEnd: (evt) => {
      // 获取拖动前后的索引
      const oldIndex = evt.oldIndex
      const newIndex = evt.newIndex
      
      // 如果位置发生变化
      if (oldIndex !== newIndex) {
        // 移动列表项
        const item = playlist.value.splice(oldIndex, 1)[0]
        playlist.value.splice(newIndex, 0, item)
        
        // 调整当前播放索引
        if (currentTrackIndex.value === oldIndex) {
          // 如果移动的是当前播放的歌曲，更新索引
          currentTrackIndex.value = newIndex
        } else if (currentTrackIndex.value > oldIndex && currentTrackIndex.value <= newIndex) {
          // 如果当前播放的歌曲在移动范围内（向后移动）
          currentTrackIndex.value--
        } else if (currentTrackIndex.value < oldIndex && currentTrackIndex.value >= newIndex) {
          // 如果当前播放的歌曲在移动范围内（向前移动）
          currentTrackIndex.value++
        }
        
        showSuccess('播放顺序已更新')
      }
    }
  })
}

// 监听播放列表变化，重新初始化Sortable
watch(playlist, () => {
  nextTick(() => {
    initSortable()
  })
}, { deep: true })

// 修改mounted钩子，添加初始化Sortable
const originalOnMounted = onMounted
onMounted(() => {
  // 调用原来的onMounted逻辑
  createAudioContext()
  lastTime = performance.now()
  animationFrame = requestAnimationFrame(updateVisualization)
  window.addEventListener('keydown', handleKeyDown)
  document.addEventListener('fullscreenchange', handleFullscreenChange)
  document.addEventListener('mousemove', handleMouseMove)
  
  // 添加用户交互监听，以解锁音频上下文
  document.addEventListener('click', async () => {
    if (audioContext.value && audioContext.value.state === 'suspended') {
      await audioContext.value.resume();
      console.log('音频上下文已恢复');
    }
  }, { once: true });
  
  // 初始化Sortable
  nextTick(() => {
    initSortable()
  })
  
  // 如果启用了歌词且有当前播放歌曲，尝试加载歌词
  if (enableLyrics.value && currentTrackIndex.value !== -1) {
    nextTick(() => {
      updateCurrentTrack();
    });
  }
})

// 修改onUnmounted钩子，添加Sortable销毁
onUnmounted(() => {
  if (animationFrame) {
    cancelAnimationFrame(animationFrame)
  }
  if (audioContext.value) {
    audioContext.value.close()
  }
  if (cursorTimeoutId) {
    clearTimeout(cursorTimeoutId)
  }
  window.removeEventListener('keydown', handleKeyDown)
  document.removeEventListener('fullscreenchange', handleFullscreenChange)
  document.removeEventListener('mousemove', handleMouseMove)
  
  // 销毁Sortable实例
  if (sortableInstance) {
    sortableInstance.destroy()
    sortableInstance = null
  }
})

const extractNeteaseId = (url) => {
  // 尝试不同格式的ID提取
  const patterns = [
    /id=(\d+)/,  // 标准格式: id=123456
    /song\/(\d+)/, // 短链接格式: song/123456
    /song\?id=(\d+)/, // 标准网页链接: song?id=123456
    /\/(\d+)\//, // 某些分享链接格式: /123456/
    /[\?&]id=(\d+)/ // 查询参数格式: ?id=123456 或 &id=123456
  ];
  
  for (const pattern of patterns) {
    const match = url.match(pattern);
    if (match && match[1]) {
      return match[1];
    }
  }
  
  return null;
}

const fetchSongMetadata = async (songId) => {
  try {
    // 构建元数据API URL
    const url = `${metadataApiUrl.value}/?id=${songId}&ids=[${songId}]`;
    console.log(`获取歌曲元数据: ${url}`);
    
    const response = await fetch(url, {
      mode: 'cors',
      credentials: 'omit'
    });
    
    if (!response.ok) {
      throw new Error(`获取元数据失败，状态码: ${response.status}`);
    }
    
    const data = await response.json();
    console.log('获取到的元数据:', data);
    
    // 检查并提取元数据
    if (data && data.songs && data.songs.length > 0) {
      const song = data.songs[0];
      const metadata = {
        title: song.name || '',
        artist: song.artists ? song.artists.map(a => a.name).join(', ') : '',
        album: song.album ? song.album.name : '',
        coverUrl: song.album && song.album.picUrl ? song.album.picUrl : null
      };
      return metadata;
    }
    
    throw new Error('未找到歌曲元数据');
  } catch (error) {
    console.error('获取歌曲元数据失败:', error);
    // 返回空对象，表示获取失败
    return { title: '', artist: '', album: '', coverUrl: null };
  }
};

// 备用方法，使用另一个API获取元数据
const fetchSongMetadataFallback = async (songId) => {
  try {
    // 使用备用API
    const url = `https://api.byfuns.top/netease/song?id=${songId}`;
    console.log(`使用备用API获取歌曲元数据: ${url}`);
    
    const response = await fetch(url);
    
    if (!response.ok) {
      throw new Error(`获取元数据失败，状态码: ${response.status}`);
    }
    
    const data = await response.json();
    console.log('获取到的备用元数据:', data);
    
    // 检查并提取元数据
    if (data && data.data) {
      const song = data.data;
      const metadata = {
        title: song.name || '',
        artist: song.ar ? song.ar.map(a => a.name).join(', ') : '',
        album: song.al ? song.al.name : '',
        coverUrl: song.al && song.al.picUrl ? song.al.picUrl : null
      };
      return metadata;
    }
    
    throw new Error('未找到歌曲元数据');
  } catch (error) {
    console.error('获取备用歌曲元数据失败:', error);
    // 返回空对象，表示获取失败
    return { title: '', artist: '', album: '', coverUrl: null };
  }
};

const addNeteaseSong = () => {
  if (!neteaseLink.value) {
    showError('请输入网易云音乐链接');
    return;
  }

  // 从链接中提取ID
  const songId = extractNeteaseId(neteaseLink.value);
  
  if (!songId) {
    showError('无效的网易云音乐链接，无法提取音乐ID');
    return;
  }
  
  console.log('提取的音乐ID:', songId);
  
  // 直接获取元数据并添加歌曲，使用空字符串作为初始标题和艺术家
  // 元数据会在fetchAndAddNeteaseSong中自动获取
  fetchAndAddNeteaseSong(songId, '加载中...', '');
  
  // 清空输入框
  neteaseLink.value = '';
}

const fetchAndAddNeteaseSong = async (songId, initialTitle, initialArtist) => {
  try {
    // 设置加载状态
    isLoading.value = true;
    loadingMessage.value = `正在获取《${initialTitle}》的信息...`;
    
    // 1. 先获取歌曲元数据
    let metadata = await fetchSongMetadata(songId);
    
    // 如果主API获取失败，尝试使用备用API
    if (!metadata.title) {
      metadata = await fetchSongMetadataFallback(songId);
    }
    
    // 如果两个API都失败，使用初始值
    const title = metadata.title || initialTitle;
    const artist = metadata.artist || initialArtist;
    
    // 2. 再获取音乐URL
    loadingMessage.value = `正在获取《${title}》的音乐链接...`;
    
    // 使用指定的API
    const apiUrl = `${proxyServerUrl.value}/?id=${songId}`;
    console.log(`获取音乐直链: ${apiUrl}`);
    
    // 请求API
    const response = await fetch(apiUrl);
    
    if (!response.ok) {
      throw new Error(`请求失败，状态码: ${response.status}`);
    }
    
    // 获取响应内容 - 假设API直接返回音频URL
    const directUrl = await response.text();
    
    if (!directUrl || !directUrl.trim().startsWith('http')) {
      throw new Error('获取的音乐直链无效，该歌曲可能需要VIP或不可用');
    }
    
    console.log('获取到的音乐直链:', directUrl);
    
    // 创建一个新的音乐对象并添加到播放列表
    const newSong = {
      name: title, // 文件名/歌曲名
      title: title + ` [id:${songId}]`, // 标题中添加网易云音乐ID，方便自动获取歌词
      artist: artist, // 艺术家
      album: metadata.album || '', // 专辑名
      url: directUrl.trim(), // 音乐URL
      file: null, // 没有本地文件
      type: 'netease', // 标记为网易云音乐类型
      id: songId, // 保存音乐ID
      coverUrl: metadata.coverUrl // 专辑封面URL
    };
    
    // 添加到播放列表
    playlist.value.push(newSong);
    
    // 如果是第一首歌，自动开始播放
    if (currentTrackIndex.value === -1 && playlist.value.length > 0) {
      currentTrackIndex.value = 0;
      await loadTrack(0);
    }
    
    // 如果启用了歌词，尝试获取歌词
    if (enableLyrics.value) {
      fetchNeteaseLyrics(songId);
    }
    
    showSuccess(`已添加《${title}》到播放列表`);
  } catch (error) {
    console.error('添加网易云音乐失败:', error);
    showError('添加失败: ' + error.message);
  } finally {
    // 清除加载状态
    isLoading.value = false;
    loadingMessage.value = '';
  }
}

// 修改重新加载网易云音乐的函数
const reloadNeteaseSong = async (index) => {
  if (index < 0 || index >= playlist.value.length) return false;
  
  const track = playlist.value[index];
  if (!track || track.type !== 'netease' || !track.id) return false;
  
  try {
    isLoading.value = true;
    loadingMessage.value = `正在重新获取《${track.title}》的信息...`;
    
    // 1. 先获取歌曲元数据
    let metadata = await fetchSongMetadata(track.id);
    
    // 如果主API获取失败，尝试使用备用API
    if (!metadata.title) {
      metadata = await fetchSongMetadataFallback(track.id);
    }
    
    // 如果有新的元数据，更新歌曲信息
    if (metadata.title) track.title = metadata.title;
    if (metadata.artist) track.artist = metadata.artist;
    if (metadata.album) track.album = metadata.album;
    if (metadata.coverUrl) track.coverUrl = metadata.coverUrl;
    
    // 2. 再获取音乐URL
    loadingMessage.value = `正在重新获取《${track.title}》的音乐链接...`;
    
    // 使用指定的API
    const apiUrl = `${proxyServerUrl.value}/?id=${track.id}`;
    console.log(`重新获取音乐直链: ${apiUrl}`);
    
    // 请求API
    const response = await fetch(apiUrl);
    
    if (!response.ok) {
      throw new Error(`请求失败，状态码: ${response.status}`);
    }
    
    // 获取响应内容 - 假设API直接返回音频URL
    const directUrl = await response.text();
    
    if (!directUrl || !directUrl.trim().startsWith('http')) {
      throw new Error('获取的音乐直链无效，该歌曲可能需要VIP或不可用');
    }
    
    // 更新播放列表中的URL
    playlist.value[index].url = directUrl.trim();
    
    // 如果当前正在播放这首歌，重新加载
    if (currentTrackIndex.value === index) {
      // 更新当前曲目信息
      currentTrackInfo.value = {
        title: track.title || '',
        artist: track.artist || '',
        fileName: track.name
      };
      
      // 更新封面图片
      if (track.coverUrl) {
        currentImage.value = track.coverUrl;
      }
      
      await loadTrack(index);
      if (isPlaying.value) {
        await audioElement.value.play();
      }
    }
    
    showSuccess(`已重新获取《${track.title}》的音乐链接`);
    isLoading.value = false;
    loadingMessage.value = '';
    return true;
  } catch (error) {
    console.error('重新加载歌曲失败:', error);
    isLoading.value = false;
    loadingMessage.value = '';
    return false;
  }
}

const showError = (message) => {
  // 显示错误通知
  showNotification(message, 'error')
}

const showSuccess = (message) => {
  // 显示成功通知
  showNotification(message, 'success')
}

// 通知系统函数
const showNotification = (message, type = 'info', duration = 3000) => {
  // 清除现有通知的定时器
  if (notification.value.timeout) {
    clearTimeout(notification.value.timeout)
  }
  
  // 设置新的通知
  notification.value = {
    show: true,
    message: message,
    type: type,
    timeout: null
  }
  
  // 设置自动关闭定时器
  notification.value.timeout = setTimeout(() => {
    closeNotification()
  }, duration)
}

const closeNotification = () => {
  notification.value.show = false
  if (notification.value.timeout) {
    clearTimeout(notification.value.timeout)
    notification.value.timeout = null
  }
}

// 添加外部音乐的函数
const addExternalMusic = () => {
  // 验证输入
  if (!externalMusicUrl.value) {
    showError('请输入音乐URL');
    return;
  }
  
  if (!externalMusicTitle.value) {
    showError('请输入歌曲名称');
    return;
  }
  
  try {
    // 检查URL是否有效
    new URL(externalMusicUrl.value);
    
    // 创建一个新的音乐对象并添加到播放列表
    const newSong = {
      name: externalMusicTitle.value, // 文件名/歌曲名
      title: externalMusicTitle.value, // 标题
      artist: externalMusicArtist.value || 'Unknown', // 艺术家
      album: '', // 专辑名
      url: externalMusicUrl.value.trim(), // 音乐URL
      file: null, // 没有本地文件
      type: 'external', // 标记为外部音乐
      id: null, // 无ID
      coverUrl: null // 无专辑封面
    };
    
    // 添加到播放列表
    playlist.value.push(newSong);
    
    // 如果是第一首歌，自动开始播放
    if (currentTrackIndex.value === -1 && playlist.value.length > 0) {
      currentTrackIndex.value = playlist.value.length - 1;
      loadTrack(currentTrackIndex.value);
    }
    
    showSuccess(`已添加《${externalMusicTitle.value}》到播放列表`);
    
    // 清空输入框
    externalMusicUrl.value = '';
    externalMusicTitle.value = '';
    externalMusicArtist.value = '';
  } catch (error) {
    showError('无效的音乐URL: ' + error.message);
  }
}

// 提取网易云音乐歌单ID的函数
const extractNeteasePlaylistId = (url) => {
  // 尝试不同格式的歌单ID提取
  const patterns = [
    /playlist\/(\d+)/, // 标准格式: playlist/123456
    /playlist\?id=(\d+)/, // 网页链接: playlist?id=123456
    /[\?&]id=(\d+)/ // 查询参数格式: ?id=123456 或 &id=123456
  ];
  
  for (const pattern of patterns) {
    const match = url.match(pattern);
    if (match && match[1]) {
      return match[1];
    }
  }
  
  return null;
}

// 获取歌单信息的函数
const fetchPlaylistInfo = async (playlistId) => {
  try {
    const url = `https://api.byfuns.top/netease/playlist?id=${playlistId}`;
    console.log(`获取歌单信息: ${url}`);
    
    const response = await fetch(url);
    
    if (!response.ok) {
      throw new Error(`请求歌单信息失败，状态码: ${response.status}`);
    }
    
    const data = await response.json();
    console.log('获取到的歌单信息:', data);
    
    if (!data.data || !data.data.tracks || !Array.isArray(data.data.tracks)) {
      throw new Error('无效的歌单数据格式');
    }
    
    return {
      title: data.data.name || '未知歌单',
      description: data.data.description || '',
      trackCount: data.data.trackCount || data.data.tracks.length,
      tracks: data.data.tracks.map(track => ({
        id: track.id,
        name: track.name,
        artist: track.ar ? track.ar.map(a => a.name).join(', ') : '',
        album: track.al ? track.al.name : '',
        coverUrl: track.al && track.al.picUrl ? track.al.picUrl : null
      }))
    };
  } catch (error) {
    console.error('获取歌单信息失败:', error);
    throw error;
  }
}

// 添加网易云音乐歌单的函数
const addNeteasePlaylist = async () => {
  if (!neteasePlaylistLink.value) {
    showError('请输入网易云音乐歌单链接');
    return;
  }

  // 从链接中提取歌单ID
  const playlistId = extractNeteasePlaylistId(neteasePlaylistLink.value);
  
  if (!playlistId) {
    showError('无效的网易云音乐歌单链接，无法提取歌单ID');
    return;
  }
  
  try {
    // 设置加载状态
    isLoading.value = true;
    loadingMessage.value = '正在获取歌单信息...';
    
    // 获取歌单信息
    const playlistInfo = await fetchPlaylistInfo(playlistId);
    
    // 提示用户正在导入
    loadingMessage.value = `正在导入歌单"${playlistInfo.title}"，共${playlistInfo.tracks.length}首歌曲...`;
    
    // 批量添加歌曲，设置最大并发数为3
    const maxConcurrent = 3;
    let completed = 0;
    let failed = 0;
    
    for (let i = 0; i < playlistInfo.tracks.length; i += maxConcurrent) {
      const batch = playlistInfo.tracks.slice(i, i + maxConcurrent);
      
      // 并发请求
      await Promise.all(batch.map(async (track) => {
        try {
          // 更新加载消息，显示进度
          loadingMessage.value = `正在导入(${completed + failed + 1}/${playlistInfo.tracks.length}): ${track.name}`;
          
          // 使用指定的API获取音乐URL
          const apiUrl = `${proxyServerUrl.value}/?id=${track.id}`;
          console.log(`获取音乐直链: ${apiUrl}`);
          
          const response = await fetch(apiUrl);
          
          if (!response.ok) {
            throw new Error(`请求失败，状态码: ${response.status}`);
          }
          
          const directUrl = await response.text();
          
          if (!directUrl || !directUrl.trim().startsWith('http')) {
            throw new Error('获取的音乐直链无效，该歌曲可能需要VIP或不可用');
          }
          
          // 创建歌曲对象并添加到播放列表
          const newSong = {
            name: track.name,
            title: track.name + ` [id:${track.id}]`, // 添加ID到标题中，用于自动获取歌词
            artist: track.artist,
            album: track.album || '',
            url: directUrl.trim(),
            file: null,
            type: 'netease',
            id: track.id,
            coverUrl: track.coverUrl
          };
          
          playlist.value.push(newSong);
          completed++;
        } catch (error) {
          console.error(`导入歌曲 ${track.name} 失败:`, error);
          failed++;
        }
      }));
    }
    
    // 如果播放列表为空，自动播放第一首
    if (completed > 0 && currentTrackIndex.value === -1) {
      currentTrackIndex.value = playlist.value.length - completed; // 指向添加的第一首歌
      await loadTrack(currentTrackIndex.value);
      if (!audioElement.value.paused) {
        isPlaying.value = true;
      }
    }
    
    // 导入完成，显示结果
    if (failed > 0) {
      showNotification(`歌单导入完成：成功${completed}首，失败${failed}首`, 'info', 5000);
    } else {
      showSuccess(`成功导入歌单"${playlistInfo.title}"的${completed}首歌曲`);
    }
    
    // 清空输入框
    neteasePlaylistLink.value = '';
  } catch (error) {
    console.error('导入歌单失败:', error);
    showError('导入歌单失败: ' + error.message);
  } finally {
    // 清除加载状态
    isLoading.value = false;
    loadingMessage.value = '';
  }
}

// 处理歌单JSON文件上传
const handlePlaylistJsonUpload = async (event) => {
  const file = event.target.files[0];
  if (!file) return;
  
  try {
    isLoading.value = true;
    loadingMessage.value = '正在解析歌单JSON文件...';
    
    // 读取文件内容
    const fileContent = await new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (e) => resolve(e.target.result);
      reader.onerror = (e) => reject(new Error('读取文件失败'));
      reader.readAsText(file);
    });
    
    // 解析JSON
    let jsonData;
    try {
      jsonData = JSON.parse(fileContent);
    } catch (e) {
      throw new Error('JSON格式错误，无法解析文件');
    }
    
    // 验证JSON格式
    if (!jsonData.playlist && !jsonData.result) {
      throw new Error('不支持的JSON格式，请上传网易云音乐歌单API返回的JSON');
    }
    
    // 提取歌单信息
    const playlistData = jsonData.playlist || jsonData.result;
    const trackList = playlistData.tracks || [];
    
    if (!trackList || !Array.isArray(trackList) || trackList.length === 0) {
      throw new Error('歌单中没有找到歌曲');
    }
    
    // 显示初始提示，然后切换到后台导入模式
    showNotification(`开始导入歌单"${playlistData.name}"，共${trackList.length}首歌曲`, 'info', 5000);
    
    // 清除加载状态，允许用户继续操作
    isLoading.value = false;
    loadingMessage.value = '';
    
    // 可以关闭添加音乐窗口，导入会在后台继续
    showAddMusic.value = false;
    
    // 初始化后台导入状态
    backgroundImport.value = {
      active: true,
      total: trackList.length,
      completed: 0,
      failed: 0,
      progress: 0,
      currentTrack: '准备导入...',
      taskId: Date.now()
    };
    
    console.log('开始导入歌单，总计歌曲:', trackList.length);
    
    // 保存当前任务ID，用于避免多个导入任务冲突
    const currentTaskId = backgroundImport.value.taskId;
    
    // 批量添加歌曲，将并发数量从10降回到3
    const maxConcurrent = 3;
    const importQueue = [...trackList]; // 创建歌曲导入队列的副本
    const processedTracks = [];
    const importedSongs = []; // 存储所有成功导入的歌曲
    
    try {
      while (importQueue.length > 0 && backgroundImport.value.taskId === currentTaskId) {
        // 取出一批歌曲
        const batch = importQueue.splice(0, maxConcurrent);
        
        console.log('处理批次，剩余队列长度:', importQueue.length);
        
        // 并发请求
        const results = await Promise.allSettled(batch.map(async (track) => {
          try {
            // 更新加载消息，显示进度
            backgroundImport.value.currentTrack = track.name;
            
            // 使用指定的API获取音乐URL
            const apiUrl = `${proxyServerUrl.value}/?id=${track.id}`;
            
            // 添加超时处理
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 15000); // 15秒超时
            
            try {
              const response = await fetch(apiUrl, { 
                signal: controller.signal,
                // 添加重试策略
                cache: 'no-cache'
              });
              
              clearTimeout(timeoutId);
              
              if (!response.ok) {
                throw new Error(`请求失败，状态码: ${response.status}`);
              }
              
              const directUrl = await response.text();
              
              if (!directUrl || !directUrl.trim().startsWith('http')) {
                throw new Error('获取的音乐直链无效，该歌曲可能需要VIP或不可用');
              }
              
              // 创建歌曲对象
              const newSong = {
                name: track.name,
                title: track.name,
                artist: track.ar ? track.ar.map(a => a.name).join(', ') : (track.artists ? track.artists.map(a => a.name).join(', ') : ''),
                album: track.al ? track.al.name : (track.album ? track.album.name : ''),
                url: directUrl.trim(),
                file: null,
                type: 'netease',
                id: track.id,
                coverUrl: track.al ? track.al.picUrl : (track.album ? track.album.picUrl : null)
              };
              
              return newSong;
            } catch (fetchError) {
              clearTimeout(timeoutId);
              if (fetchError.name === 'AbortError') {
                throw new Error('请求超时');
              }
              throw fetchError;
            }
          } catch (error) {
            console.error(`导入歌曲 ${track.name} 失败:`, error);
            throw error;
          }
        }));
        
        // 处理结果
        results.forEach((result, index) => {
          if (result.status === 'fulfilled') {
            processedTracks.push(result.value);
            backgroundImport.value.completed++;
          } else {
            backgroundImport.value.failed++;
          }
          
          // 更新进度
          backgroundImport.value.progress = Math.floor((backgroundImport.value.completed + backgroundImport.value.failed) / backgroundImport.value.total * 100);
        });
        
        // 每处理一批就添加到播放列表，这样用户可以更早开始听第一首
        if (processedTracks.length > 0) {
          console.log('添加到播放列表，此批歌曲数:', processedTracks.length);
          
          // 将本批次歌曲添加到总导入列表
          importedSongs.push(...processedTracks);
          
          // 直接修改响应式数组
          for (const track of processedTracks) {
            playlist.value.push(track);
          }
          
          // 如果播放列表之前为空，开始播放第一首
          if (currentTrackIndex.value === -1 && processedTracks.length > 0) {
            const firstSongIndex = playlist.value.length - processedTracks.length;
            console.log('播放列表之前为空，开始播放第一首歌曲，索引:', firstSongIndex);
            
            // 确保播放列表有歌曲
            if (playlist.value.length > 0) {
              currentTrackIndex.value = firstSongIndex;
              nextTick(async () => {
                await loadTrack(currentTrackIndex.value);
                if (!audioElement.value.paused) {
                  isPlaying.value = true;
                }
              });
            }
          }
          
          // 清空已处理队列，准备下一批
          processedTracks.length = 0;
        }
        
        // 让用户界面有机会更新，避免阻塞
        await new Promise(resolve => setTimeout(resolve, 100));
      }
    } catch (importError) {
      console.error('导入过程中发生错误:', importError);
      if (backgroundImport.value.taskId === currentTaskId) {
        showError(`导入过程中断: ${importError.message}`);
      }
    }
    
    // 确保所有歌曲都被添加到播放列表
    if (importedSongs.length > 0 && playlist.value.length === 0) {
      console.log('直接设置播放列表，歌曲数:', importedSongs.length);
      playlist.value = [...importedSongs];
      
      // 如果播放列表之前为空，开始播放第一首
      if (currentTrackIndex.value === -1) {
        currentTrackIndex.value = 0;
        nextTick(async () => {
          await loadTrack(0);
          if (!audioElement.value.paused) {
            isPlaying.value = true;
          }
        });
      }
    }
    
    // 完成导入
    if (backgroundImport.value.taskId === currentTaskId) {
      // 确保进度显示100%
      backgroundImport.value.progress = 100;
      
      // 导入后播放列表诊断
      console.log('导入完成，导入歌曲数:', importedSongs.length, '播放列表长度:', playlist.value.length);
      
      if (playlist.value.length === 0 && importedSongs.length > 0) {
        console.warn('播放列表为空但有导入歌曲，强制设置播放列表');
        playlist.value = [...importedSongs];
      }
      
      if (backgroundImport.value.failed > 0) {
        showNotification(`歌单导入完成：成功${backgroundImport.value.completed}首，失败${backgroundImport.value.failed}首`, 'info', 5000);
      } else if (backgroundImport.value.completed > 0) {
        showSuccess(`成功导入歌单"${playlistData.name}"的${backgroundImport.value.completed}首歌曲`);
      } else {
        showError('导入失败：无法获取任何歌曲');
      }
      
      // 延迟一段时间后隐藏导入状态条
      setTimeout(() => {
        if (backgroundImport.value.taskId === currentTaskId) {
          backgroundImport.value.active = false;
        }
      }, 3000);
    }
    
    // 清空文件选择器
    event.target.value = '';
  } catch (error) {
    console.error('处理歌单JSON失败:', error);
    showError('导入歌单失败: ' + error.message);
    event.target.value = '';
    isLoading.value = false;
    loadingMessage.value = '';
    // 确保后台导入指示器被隐藏
    backgroundImport.value.active = false;
  }
}

// 取消后台导入任务
const cancelBackgroundImport = () => {
  if (backgroundImport.value.active) {
    backgroundImport.value.taskId = null;
    showNotification('已取消歌单导入', 'info');
    setTimeout(() => {
      backgroundImport.value.active = false;
    }, 1000);
  }
}

// 获取歌单JSON的辅助功能
const getPlaylistJsonHelp = () => {
  // 使用原生JS的prompt函数获取用户输入
  const playlistLink = prompt('请输入网易云音乐歌单链接:');
  if (!playlistLink) return;
  
  // 提取歌单ID
  const playlistId = extractNeteasePlaylistId(playlistLink);
  if (!playlistId) {
    showError('无效的网易云音乐歌单链接，无法提取歌单ID');
    return;
  }
  
  // 构建API URL
  const apiUrl = `https://music.163.com/api/playlist/detail?id=${playlistId}`;
  
  // 打开新窗口跳转到API地址
  window.open(apiUrl, '_blank');
  
  // 显示提示信息
  showNotification('请在新窗口中保存返回的JSON内容为文件，然后上传到此处', 'info', 10000);
}
// 检查歌曲标题是否需要滚动
const shouldScrollTitle = computed(() => {
  const title = splitFileName(currentTrackInfo.value.title || currentTrackInfo.value.fileName).main;
  // 在歌词模式下不滚动标题
  if (enableLyrics.value) {
    return false;
  }
  // 只有当标题超过25个字符时才滚动
  return title && title.length > 25;
});

// 导出播放列表为JSON文件
const exportPlaylist = () => {
  console.log('开始导出播放列表，列表长度:', playlist.value.length);
  
  if (playlist.value.length === 0) {
    showError('播放列表为空，无法导出');
    return;
  }
  
  try {
    // 转换播放列表为兼容格式
    const exportData = {
      playlist: {
        name: `我的播放列表 - ${new Date().toLocaleDateString()}`,
        description: `通过音乐可视化应用导出，共${playlist.value.length}首歌曲`,
        tracks: playlist.value.map(track => {
          return {
            id: track.id || generateTempId(),
            name: track.title || track.name || '未知歌曲',
            ar: track.artist ? [{ name: track.artist }] : [{ name: '未知艺术家' }],
            al: {
              name: track.album || '未知专辑',
              picUrl: track.coverUrl || ''
            }
          };
        })
      }
    };
    
    console.log('已格式化播放列表数据，准备下载');
    
    // 将数据转换为格式化的JSON字符串
    const jsonContent = JSON.stringify(exportData, null, 2);
    console.log('JSON长度:', jsonContent.length);
    
    // 使用更可靠的下载方法
    const blob = new Blob([jsonContent], { type: 'application/json' });
    console.log('已创建Blob对象');
    
    // 使用改进的下载方法
    downloadFile(blob, `playlist-${Date.now()}.json`);
  } catch (error) {
    console.error('导出播放列表失败:', error);
    showError('导出播放列表失败: ' + error.message);
  }
};

// 抽取独立的下载文件函数，便于复用和测试
const downloadFile = (blob, filename) => {
  try {
    // 兼容旧版浏览器的下载实现
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
      // 适用于IE和Edge
      window.navigator.msSaveOrOpenBlob(blob, filename);
      console.log('使用msSaveOrOpenBlob方法下载');
      showSuccess('播放列表已成功导出');
      return;
    }
    
    // 标准现代浏览器实现
    const url = URL.createObjectURL(blob);
    console.log('已创建对象URL:', url);
    
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    a.style.display = 'none';
    
    // 确保元素被添加到DOM中
    document.body.appendChild(a);
    console.log('已添加下载元素到DOM');
    
    // 触发点击事件 - 尝试使用不同的方法
    try {
      // 方法1: 默认点击
      a.click();
      console.log('已触发点击事件 (方法1)');
    } catch (e) {
      console.warn('点击方法1失败，尝试方法2:', e);
      try {
        // 方法2: MouseEvent
        const event = new MouseEvent('click');
        a.dispatchEvent(event);
        console.log('已触发点击事件 (方法2)');
      } catch (e2) {
        console.warn('点击方法2失败，尝试方法3:', e2);
        // 方法3: 创建和触发自定义事件
        const event = document.createEvent('MouseEvents');
        event.initEvent('click', true, true);
        a.dispatchEvent(event);
        console.log('已触发点击事件 (方法3)');
      }
    }
    
    // 延迟清理
    setTimeout(() => {
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      console.log('清理完成');
    }, 100);
    
    showSuccess('播放列表已成功导出');
  } catch (error) {
    console.error('下载文件失败:', error);
    showError('下载文件失败: ' + error.message);
    
    // 尝试提供备用下载方法
    const jsonContent = URL.createObjectURL(blob);
    console.log('如果下载未自动开始，请直接访问并保存此链接:', jsonContent);
    showNotification('如果下载未开始，请打开浏览器控制台查看下载链接', 'info', 10000);
  }
};

// 为没有ID的歌曲生成临时ID
const generateTempId = () => {
  return 'temp-' + Math.random().toString(36).substring(2, 15);
}

// 处理歌词文件上传
const handleLrcChange = (event) => {
  const file = event.target.files[0];
  if (file) {
    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const text = e.target.result;
        currentLyrics.value = parseLyrics(text);
      } catch (error) {
        console.error('解析歌词失败:', error);
        currentLyrics.value = [{ text: '歌词解析失败，请检查文件格式', time: 0 }];
      }
    };
    reader.readAsText(file);
  }
}

// 获取歌词的函数
const fetchLyrics = async (url) => {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error('无法获取歌词');
    }
    const text = await response.text();
    currentLyrics.value = parseLyrics(text);
  } catch (error) {
    console.error('获取歌词失败:', error);
    currentLyrics.value = [
      { text: '歌词加载失败，请检查文件格式或网络连接', time: 0 }
    ];
  }
}

// 解析歌词的函数
const parseLyrics = (text) => {
  const lines = text.split('\n');
  const timeRegExp = /\[(\d{2}):(\d{2})\.(\d{2,3})\]/;
  const lyrics = [];

  lines.forEach(line => {
    // 跳过空行
    if (!line.trim()) return;
    
    const timeMatches = line.match(new RegExp(timeRegExp, 'g'));
    if (!timeMatches) return;
    
    let content = line.replace(new RegExp(timeRegExp, 'g'), '').trim();
    // 跳过没有内容的行
    if (!content) return;
    
    timeMatches.forEach(timeMatch => {
      const match = timeMatch.match(timeRegExp);
      if (match) {
        const minutes = parseInt(match[1]);
        const seconds = parseInt(match[2]);
        // 统一毫秒格式
        let milliseconds = parseInt(match[3]);
        if (match[3].length === 2) milliseconds *= 10;
        
        const time = minutes * 60 * 1000 + seconds * 1000 + milliseconds;
        lyrics.push({
          time,
          text: content
        });
      }
    });
  });
  
  // 按时间排序
  return lyrics.sort((a, b) => a.time - b.time);
};

// 歌词显示组件
const currentLyrics = ref([]);
const currentLyricIndex = ref(0);

// 歌词滚动函数
const scrollLyrics = () => {
  const lyricsContent = document.getElementById('lyrics-content');
  const lyricsHeight = lyricsContent.offsetHeight;
  const scrollTop = lyricsContent.scrollTop;
  const clientHeight = lyricsContent.clientHeight;

  if (scrollTop + clientHeight >= lyricsHeight) {
    lyricsContent.scrollTop = 0;
  } else {
    lyricsContent.scrollTop += 1;
  }
}

// 歌词滚动监听
watch(currentLyricIndex, (newIndex) => {
  if (newIndex >= 0 && newIndex < currentLyrics.value.length) {
    scrollLyrics();
  }
});

// 歌词滚动指令
const scrollLyricsDirective = {
  mounted(el) {
    el.addEventListener('scroll', scrollLyrics);
  },
  unmounted(el) {
    el.removeEventListener('scroll', scrollLyrics);
  }
};

// 歌词显示组件
const lyricsContent = ref(null);

// 定义响应式变量
const enableLyrics = ref(false);

// 在歌词容器的ref上增加日志输出
const lyricsContainer = ref(null);

// 添加歌词加载时的日志
const updateCurrentTrack = () => {
  if (playlist.value.length === 0 || currentTrackIndex.value === -1) {
    console.log("无法更新当前歌曲信息：播放列表为空或无当前曲目");
    return;
  }
  
  const currentTrack = playlist.value[currentTrackIndex.value];
  console.log("更新当前歌曲信息:", currentTrack);
  
  currentTrackInfo.value = {
    title: currentTrack.title || '',
    artist: currentTrack.artist || '',
    fileName: currentTrack.name
  };
  
  // 重置歌词
  currentLyrics.value = [];
  currentLyricIndex.value = -1;
  
  // 如果启用歌词，尝试获取歌词
  if (enableLyrics.value) {
    console.log("歌词已启用，尝试获取歌词");
    // 检查是否是网易云音乐类型
    if (currentTrack.type === 'netease' && currentTrack.id) {
      console.log("检测到网易云音乐，ID:", currentTrack.id);
      // 获取网易云音乐歌词
      fetchNeteaseLyrics(currentTrack.id);
      return;
    }
    
    // 检查是否是网易云音乐ID
    const neteaseMusicIdMatch = currentTrack.title?.match(/\[id:(\d+)\]/);
    if (neteaseMusicIdMatch && neteaseMusicIdMatch[1]) {
      console.log("从标题中检测到网易云音乐ID:", neteaseMusicIdMatch[1]);
      // 获取网易云音乐歌词
      fetchNeteaseLyrics(neteaseMusicIdMatch[1]);
      return;
    }
    
    console.log("未找到网易云音乐ID，显示默认提示");
    // 默认显示无歌词提示
    currentLyrics.value = [{ text: '无歌词，请手动导入LRC文件或输入网易云音乐ID', time: 0 }];
  } else {
    console.log("歌词未启用");
  }
};

// 修改歌词获取函数，添加详细日志
const fetchNeteaseLyrics = async (musicId) => {
  try {
    console.log("开始获取网易云音乐歌词，ID:", musicId);
    currentLyrics.value = [{ text: '歌词加载中...', time: 0 }];
    
    // 尝试不使用代理直接获取
    const apiUrl = `https://music.163.com/api/song/lyric?id=${musicId}&lv=1&kv=1&tv=-1`;
    console.log("使用API地址:", apiUrl);
    
    try {
      // 先尝试直接获取
      console.log("尝试直接获取歌词");
      const response = await fetch(apiUrl);
      const data = await response.json();
      console.log("API返回数据:", data);
      
      if (data && data.lrc && data.lrc.lyric) {
        console.log("成功获取歌词，开始解析");
        currentLyrics.value = parseLyrics(data.lrc.lyric);
        console.log("解析完成，歌词行数:", currentLyrics.value.length);
        return;
      } else {
        console.log("API返回数据中没有歌词内容");
      }
    } catch (directError) {
      console.error("直接获取歌词失败，尝试使用备用方法", directError);
    }
    
    // 如果直接获取失败，尝试使用备用API
    console.log("尝试使用备用API获取歌词");
    const backupApiUrl = `https://api.byfuns.top/netease/lyric?id=${musicId}`;
    const backupResponse = await fetch(backupApiUrl);
    const backupData = await backupResponse.json();
    console.log("备用API返回数据:", backupData);
    
    if (backupData && backupData.data && backupData.data.lrc) {
      console.log("成功从备用API获取歌词，开始解析");
      currentLyrics.value = parseLyrics(backupData.data.lrc);
      console.log("解析完成，歌词行数:", currentLyrics.value.length);
    } else {
      console.log("备用API返回数据中没有歌词内容");
      currentLyrics.value = [{ text: '未找到歌词', time: 0 }];
    }
  } catch (error) {
    console.error('获取网易云音乐歌词失败:', error);
    currentLyrics.value = [{ text: '获取歌词失败，请检查网络连接', time: 0 }];
  }
};

// 确保在播放列表变化时，自动更新歌词
watch(playlist, () => {
  if (enableLyrics.value && currentTrackIndex.value !== -1) {
    console.log("播放列表变化，尝试更新歌词");
    nextTick(() => {
      updateCurrentTrack();
    });
  }
}, { deep: true });

// 确保在启用歌词时，立即显示歌词容器
watch(enableLyrics, (newValue) => {
  console.log("歌词设置变更为:", newValue);
  if (newValue) {
    console.log("歌词已启用，检查当前播放状态");
    if (currentTrackIndex.value !== -1) {
      console.log("当前有正在播放的歌曲，尝试获取歌词");
      nextTick(() => {
        updateCurrentTrack();
      });
    } else {
      console.log("当前无正在播放的歌曲");
    }
  }
});

// 添加一个专门处理歌词滚动的函数
const scrollToActiveLyric = (index) => {
  // 确保DOM已经更新
  nextTick(() => {
    // 使用原生DOM API，确保可靠性
    const lyricElement = document.getElementById(`lyric-${index}`);
    if (!lyricElement) {
      console.warn("找不到当前歌词元素:", index);
      return;
    }
    
    // 寻找正确的滚动容器
    const lyricsContainer = document.querySelector('.lyrics-container-integrated');
    if (!lyricsContainer) {
      console.warn("找不到歌词容器");
      return;
    }
    
    // 计算当前歌词到容器顶部的距离
    const containerRect = lyricsContainer.getBoundingClientRect();
    const lyricRect = lyricElement.getBoundingClientRect();
    
    // 确保当前歌词在容器中间
    const offsetTop = lyricElement.offsetTop;
    const containerHeight = lyricsContainer.clientHeight;
    const targetPosition = offsetTop - (containerHeight / 2) + (lyricElement.offsetHeight / 2);
    
    console.log(`滚动歌词 ${index} 到位置 ${targetPosition}，歌词高度: ${lyricElement.offsetHeight}`);
    
    // 使用scrollTo方法带平滑效果
    lyricsContainer.scrollTo({
      top: targetPosition,
      behavior: 'auto' // 使用'auto'而非'smooth'以确保立即定位
    });
    
    // 备用方法：直接设置scrollTop
    lyricsContainer.scrollTop = targetPosition;
  });
};

// 修复audioTimeUpdate函数
const audioTimeUpdate = () => {
  if (!audioElement.value || !enableLyrics.value || currentLyrics.value.length === 0) return;
  
  const currentTimeMs = audioElement.value.currentTime * 1000; // 转换为毫秒
  
  // 找到当前应该显示的歌词
  let foundIndex = -1;
  for (let i = currentLyrics.value.length - 1; i >= 0; i--) {
    if (currentLyrics.value[i].time <= currentTimeMs) {
      foundIndex = i;
      break;
    }
  }
  
  // 如果找到了匹配的歌词行
  if (foundIndex !== -1) {
    // 更新当前歌词索引
    if (currentLyricIndex.value !== foundIndex) {
      currentLyricIndex.value = foundIndex;
      console.log(`切换到歌词索引: ${foundIndex}`);
      
      // 当歌词行变化时，强制滚动到该行
      scrollToActiveLyric(foundIndex);
    } else {
      // 即使当前行没有变化，也要每隔一段时间确保歌词在中间位置
      // 这样可以防止用户手动滚动后歌词位置偏移
      if (Date.now() - lastAutoScrollTime > 2000) { // 每2秒检查一次
        scrollToActiveLyric(foundIndex);
        lastAutoScrollTime = Date.now();
      }
    }
  }
};

// 监听enableLyrics变化
watch(enableLyrics, (newValue) => {
  if (newValue && currentTrackIndex.value !== -1) {
    // 如果启用歌词，且有正在播放的歌曲，则尝试加载歌词
    updateCurrentTrack();
  } else {
    // 如果禁用歌词，清空歌词
    currentLyrics.value = [];
    currentLyricIndex.value = -1;
  }
});

// 监听currentTrackIndex变化，更新当前播放歌曲
watch(currentTrackIndex, (newValue) => {
  if (newValue !== -1) {
    updateCurrentTrack();
  }
});

// 初始化设置，确保设置可以被保存
onMounted(() => {
  // 从本地存储加载设置
  const savedSettings = localStorage.getItem('musicVisualizerSettings');
  if (savedSettings) {
    try {
      const settings = JSON.parse(savedSettings);
      // 设置启用歌词
      if (settings.enableLyrics !== undefined) {
        enableLyrics.value = settings.enableLyrics;
      }
      
      // 加载其他设置
      if (settings.enableRedEffect !== undefined) {
        enableRedEffect.value = settings.enableRedEffect;
      }
      // ... 其他设置加载
    } catch (e) {
      console.error('加载设置时出错:', e);
    }
  }
  
  // ... 其他初始化代码
})

// 更新closeSettings函数，删除冗余代码
const closeSettings = () => {
  showSettings.value = false;
  saveSettings();
}

// ... existing code ...

// 在<script>部分添加网易云ID变量和手动获取歌词函数
// 定义响应式变量
const neteaseMusicId = ref('');

// 手动获取网易云歌词
const fetchNeteaseLyricsManually = () => {
  if (!neteaseMusicId.value) {
    showError('请输入网易云音乐ID');
    return;
  }
  
  fetchNeteaseLyrics(neteaseMusicId.value);
};

// 添加文字颜色计算
const textColorAdaptive = computed(() => {
  // 颜色色调在0-240范围，0为红色，120为绿色，240为蓝色
  // 生成对应的HSL颜色，确保文字与背景有足够对比度
  const hue = colorHue.value;
  
  // 当背景色调接近120（绿色）时，使用较暗的文字
  if (hue > 90 && hue < 150) {
    return 'rgba(255, 255, 255, 0.95)';
  }
  
  // 对于其他颜色，使用明亮的白色文字
  return 'rgba(255, 255, 255, 0.95)';
});

const textColorSecondaryAdaptive = computed(() => {
  // 使用相同色调但透明度更低的颜色作为次要文字颜色
  return 'rgba(255, 255, 255, 0.7)';
});

// 检查歌曲标题是否需要滚动 - 优化后的版本
const shouldScrollTitleNew = computed(() => {
  const title = splitFileName(currentTrackInfo.value.title || currentTrackInfo.value.fileName).main;
  // 在歌词模式下不滚动标题
  if (enableLyrics.value) {
    return false;
  }
  // 只有当标题超过25个字符时才滚动
  return title && title.length > 25;
});

// 歌词相关变量
// const currentLyrics = ref([]);  // 已在其他地方声明
// const currentLyricIndex = ref(0);  // 已在其他地方声明
// const enableLyrics = ref(false);  // 已在其他地方声明
// const lyricsContainer = ref(null);  // 已在其他地方声明
// const lyricsContent = ref(null);  // 已在其他地方声明
// const showLyricsDebug = ref(false);  // 已在其他地方声明
let lastAutoScrollTime = 0; // 记录上次自动滚动的时间
</script>

<style>
body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  background-color: #1a1a1a;
}

.visualizer-container {
  position: relative;
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background-color: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(10px);
}

.background-image {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: blur(20px);
  opacity: 0.7;
  z-index: -2;
  transform: scale(1.2);
  transform-origin: center;
}

.background-image.red-filter-fading-in {
  animation: redFilterFadeIn 5s forwards;
}

.background-image.red-filter-visible {
  filter: blur(20px) sepia(50%) hue-rotate(-50deg) saturate(3);
}

.background-image.red-filter-fading-out {
  animation: redFilterFadeOut 5s forwards;
}

@keyframes redFilterFadeIn {
  from { filter: blur(20px); }
  to { filter: blur(20px) sepia(50%) hue-rotate(-50deg) saturate(3); }
}

@keyframes redFilterFadeOut {
  from { filter: blur(20px) sepia(50%) hue-rotate(-50deg) saturate(3); }
  to { filter: blur(20px); }
}

.waveform-wrapper {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  z-index: 0;
  gap: -1px;
}

.waveform-container {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1px;
  height: 200px;
  padding: 0 20px;
  flex: 1;
  background: transparent;
  margin: 0 -0.5px;
}

.waveform-container.left {
  transform: scaleX(-1);
  padding-right: 0;
}

.waveform-container.right {
  padding-left: 0;
}

.waveform-bar {
  flex: 1;
  min-width: 1px;
  border-radius: 1px;
  animation: gradientFlow infinite;
  transform-origin: bottom;
  transition: height 0.05s ease-out, background 0.3s ease-out;
  margin: 0;
  flex-shrink: 0;
  max-width: 10px;
}

.cover-container {
  position: relative;
  width: 220px;
  height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
  transform-origin: center;
  transition: transform 0.1s ease-out;
  cursor: pointer;
}

.cover-container.playing {
  transform: scale(1.2);
}

.progress-ring {
  position: absolute;
  width: 220px;
  height: 220px;
  transform: rotate(-90deg);
  z-index: 3;
}

.progress-ring:hover .progress-ring__circle-bg {
  stroke: rgba(255, 255, 255, 0.2);
}

.progress-ring__circle {
  width: 100%;
  height: 100%;
}

.progress-ring__circle-bg {
  stroke: rgba(255, 255, 255, 0.1);
  transition: stroke 0.3s ease;
}

.progress-ring__circle-progress {
  stroke-linecap: round;
  transition: stroke-dasharray 0.1s linear, stroke 0.3s ease;
}

.visualizer-image {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
  position: relative;
  z-index: 1;
  margin: 0;
  display: block;
  pointer-events: none;
}

.visualizer-image.playing {
  box-shadow: 0 0 30px rgba(255, 255, 255, 0.3);
}

.visualizer-image:hover {
  transform: scale(1.05);
}

.settings-button {
  position: fixed;
  top: 20px;
  right: 20px;
  background: none;
  border: none;
  color: white;
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.3s ease;
  z-index: 10;
  padding: 0;
  width: 24px;
  height: 24px;
}

.settings-button:hover {
  opacity: 1;
}

.settings-button svg {
  width: 100%;
  height: 100%;
}

.settings-modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  backdrop-filter: blur(5px);
}

.settings-content {
  background: rgba(30, 30, 30, 0.9);
  padding: 20px;
  border-radius: 10px;
  width: 90%;
  max-width: 800px;
  color: white;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}

.settings-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.close-button {
  background: none;
  border: none;
  color: white;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.3s ease;
}

.close-button:hover {
  opacity: 1;
}

.settings-columns {
  display: flex;
  flex: 1;
  overflow: hidden;
  min-height: 300px;
}

.settings-column {
  flex: 1;
  padding: 0 15px;
}

.settings-left {
  flex: 1;
  max-width: 450px;
  padding-right: 20px;
  overflow-y: auto;
  max-height: 60vh;
}

.settings-right {
  overflow-y: auto;
  max-height: 60vh;
  padding-left: 20px;
  display: flex;
  flex-direction: column;
  min-width: 300px;
}

.settings-divider {
  width: 1px;
  background: rgba(255, 255, 255, 0.2);
  margin: 0 5px;
}

.no-playlist {
  color: rgba(255, 255, 255, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
}

.playlist-items {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-height: 50vh;
  min-height: 300px;
  margin-top: 10px;
  margin-bottom: 10px;
}

.settings-footer {
  margin-top: 20px;
  text-align: right;
}

.settings-footer .btn {
  padding: 8px 20px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: white;
  transition: all 0.3s ease;
}

.settings-footer .btn:hover {
  background: rgba(255, 255, 255, 0.2);
  border-color: rgba(255, 255, 255, 0.3);
}

.controls {
  display: none;
}

.track-info {
  position: absolute;
  bottom: 70px;
  text-align: center;
  color: white;
  z-index: 2;
  background: transparent;
  padding: 10px 20px;
  border-radius: 10px;
  backdrop-filter: none;
  transition: opacity 0.3s ease;
  max-width: 80%;
}

.track-title {
  font-size: 40px;
  font-weight: bold;
  margin-bottom: 5px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: white;
  transition: font-size 0.3s ease;
}

.track-title.playing {
  font-size: 20px;
}

.track-prefix {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.6);
  margin-bottom: 5px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.track-artist {
  font-size: 14px;
  opacity: 0.8;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.keyboard-tips {
  position: fixed;
  bottom: 20px;
  left: 20px;
  background: rgba(0, 0, 0, 0.5);
  padding: 10px;
  border-radius: 5px;
  color: white;
  font-size: 14px;
  display: flex;
  gap: 15px;
  z-index: 5;
  backdrop-filter: blur(5px);
  opacity: 0.7;
  transition: opacity 0.3s ease;
}

.keyboard-tips:hover {
  opacity: 1;
}

.tip {
  display: flex;
  align-items: center;
  gap: 8px;
}

.key {
  display: inline-block;
  padding: 2px 8px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 3px;
  min-width: 24px;
  text-align: center;
}

.form-check {
  display: flex;
  align-items: center;
  gap: 10px;
}

.form-check-input {
  margin-top: 0;
  width: 16px;
  height: 16px;
  background-color: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.3);
  cursor: pointer;
}

.form-check-input:checked {
  background-color: rgba(255, 255, 255, 0.5);
}

.form-check-label {
  font-size: 14px;
  color: white;
  cursor: pointer;
}

.playlist-item {
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  color: white;
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 45px;
  flex-shrink: 0;
  margin-bottom: 5px;
}

.playlist-item-info {
  cursor: pointer;
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: transparent;
}

.playlist-item-main {
  font-weight: bold;
  color: white;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.playlist-item-prefix {
  font-size: 0.8em;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.playlist-item-remove {
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.5);
  cursor: pointer;
  padding: 3px;
  margin-left: 5px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s ease;
}

.playlist-item-remove:hover {
  color: white;
  background: rgba(255, 0, 0, 0.3);
}

.playlist-item:hover {
  background: rgba(255, 255, 255, 0.2);
}

.playlist-item.active {
  background: rgba(255, 255, 255, 0.3);
  border-left: 3px solid white;
  box-shadow: 0 0 10px rgba(255, 255, 255, 0.2);
}

.empty-playlist-notice {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  background-color: rgba(255, 50, 50, 0.8);
  color: white;
  padding: 8px 16px;
  border-radius: 4px;
  font-size: 14px;
  z-index: 110;
  animation: fadeInOut 3s forwards;
}

@keyframes fadeInOut {
  0% { opacity: 0; }
  10% { opacity: 1; }
  80% { opacity: 1; }
  100% { opacity: 0; }
}

.red-overlay {
  display: none;
}

.netease-input-group {
  display: flex;
  gap: 8px;
  margin-bottom: 8px;
}

.netease-add-btn {
  white-space: nowrap;
}

.loading-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  backdrop-filter: blur(5px);
}

.loading-spinner {
  width: 50px;
  height: 50px;
  border: 5px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: white;
  animation: spin 1s linear infinite;
  margin-bottom: 20px;
}

.loading-message {
  color: white;
  font-size: 18px;
  text-align: center;
  max-width: 80%;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* 加号按钮样式 */
.add-button {
  position: fixed;
  top: 20px;
  right: 60px; /* 位于设置按钮左侧 */
  background: none;
  border: none;
  color: white;
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.3s ease;
  z-index: 10;
  padding: 0;
  width: 24px;
  height: 24px;
}

.add-button:hover {
  opacity: 1;
}

.add-button svg {
  width: 100%;
  height: 100%;
}

/* 设置内容样式 */
.settings-body {
  overflow-y: auto;
  max-height: 60vh;
  padding: 0 15px;
  margin-bottom: 20px;
}

/* 通知系统样式 */
.notification {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  padding: 12px 20px;
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  z-index: 1000;
  display: flex;
  justify-content: center;
  backdrop-filter: blur(5px);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}

.notification-content {
  display: flex;
  align-items: center;
  max-width: 80%;
  margin: 0 auto;
}

.notification-message {
  flex: 1;
  text-align: center;
}

.notification-close {
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.7);
  cursor: pointer;
  padding: 5px;
  margin-left: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  transition: all 0.2s;
}

.notification-close:hover {
  color: white;
  background-color: rgba(255, 255, 255, 0.1);
}

.notification.success {
  background-color: rgba(40, 167, 69, 0.9);
}

.notification.error {
  background-color: rgba(220, 53, 69, 0.9);
}

.notification.info {
  background-color: rgba(0, 123, 255, 0.9);
}

/* 滑动过渡效果 */
.notification-slide-enter-active,
.notification-slide-leave-active {
  transition: transform 0.3s ease-out;
}

.notification-slide-enter-from,
.notification-slide-leave-to {
  transform: translateY(-100%);
}

.notification-slide-enter-to,
.notification-slide-leave-from {
  transform: translateY(0);
}

/* 拖拽相关样式 */
.playlist-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
}

.playlist-header-title {
  font-weight: bold;
  font-size: 16px;
}

.playlist-header-hint {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.5);
}

.playlist-item-drag-handle {
  display: flex;
  align-items: center;
  padding: 4px;
  cursor: grab;
  color: rgba(255, 255, 255, 0.5);
  opacity: 0.5;
  transition: opacity 0.3s;
}

.playlist-item:hover .playlist-item-drag-handle {
  opacity: 1;
}

.playlist-item-drag-handle:active {
  cursor: grabbing;
}

.playlist-item {
  padding: 8px 12px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  color: white;
  cursor: pointer;
  transition: all 0.3s ease;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 45px;
  flex-shrink: 0;
  margin-bottom: 5px;
}

/* 拖动时的样式 */
.playlist-item-ghost {
  opacity: 0.5;
  background: rgba(100, 100, 255, 0.2);
}

.playlist-item-chosen {
  background: rgba(255, 255, 255, 0.3);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
}

.playlist-item-drag {
  opacity: 0.8;
  transform: scale(1.02);
}

.netease-help-btn {
  width: 100%;
  margin-bottom: 5px;
}

/* 播放列表中的导入状态样式 */
.playlist-import-status {
  margin-bottom: 15px;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
  padding: 10px;
  color: white;
}

.bg-import-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 5px;
  font-weight: bold;
}

.bg-import-cancel {
  background: none;
  border: none;
  color: #ff5252;
  padding: 2px 5px;
  cursor: pointer;
  font-size: 12px;
  opacity: 0.8;
  transition: opacity 0.2s;
}

.bg-import-cancel:hover {
  opacity: 1;
}

.bg-import-content {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.bg-import-progress {
  width: 100%;
  height: 6px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 3px;
  overflow: hidden;
}

.bg-import-progress-bar {
  height: 100%;
  background: linear-gradient(to right, #1DB954, #1ED760);
  transition: width 0.3s ease;
}

.bg-import-stats {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  margin-top: 5px;
}

.bg-import-failed {
  color: #ff5252;
}

.bg-import-current {
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.8;
}

/* 歌名滚动效果 */
.track-title.scroll-text {
  overflow: hidden;
  white-space: nowrap;
  position: relative;
  max-width: 90%;
  margin: 0 auto;
}

.track-title .scroll-text-inner {
  display: inline-block;
  padding-right: 50px; /* 在文本末尾添加更多空间，使滚动更流畅 */
  animation: marquee 15s linear infinite;
  /* 移除暂停状态，使其始终自动滚动 */
}

/* 给滚动添加一个停顿 */
@keyframes marquee {
  0%, 10% {
    transform: translateX(0);
  }
  90%, 100% {
    transform: translateX(-100%);
  }
}

/* 适配播放状态 */
.track-title.playing.scroll-text .scroll-text-inner {
  font-size: 18px; /* 调整播放状态下的字体大小 */
}

/* 设置章节样式 */
.settings-section {
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  padding-top: 15px;
  margin-top: 15px;
}

.settings-section-title {
  margin-bottom: 12px;
  font-size: 16px;
  color: rgba(255, 255, 255, 0.9);
}

.btn-group {
  display: flex;
}

.btn-group .btn {
  flex: 1;
  margin-right: 5px;
}

.btn-group .btn:last-child {
  margin-right: 0;
}

.lyrics-container {
  position: fixed;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
  width: 80%;
  max-width: 800px;
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 15px;
  border-radius: 10px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.7);
  max-height: 200px;
  overflow-y: auto;
  z-index: 1000;
  backdrop-filter: blur(10px);
  transition: opacity 0.3s;
}

.lyrics-wrapper {
  max-height: 170px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
}

.lyrics-wrapper::-webkit-scrollbar {
  width: 5px;
}

.lyrics-wrapper::-webkit-scrollbar-track {
  background: transparent; 
}

.lyrics-wrapper::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.3);
  border-radius: 10px;
}

.lyrics-content {
  text-align: center;
  padding: 10px 0;
}

.lyric-line {
  padding: 5px 0;
  transition: all 0.3s ease;
  opacity: 0.7;
  font-size: 14px;
  line-height: 1.5;
}

.lyric-line.active {
  opacity: 1;
  font-size: 16px;
  font-weight: bold;
  color: #1db954; /* Spotify绿色 */
  text-shadow: 0 0 5px rgba(29, 185, 84, 0.5);
}

/* 添加歌词调试样式 */
.lyrics-debug {
  margin-bottom: 10px;
  padding: 5px;
  background: rgba(255, 0, 0, 0.2);
  border-radius: 5px;
  font-size: 12px;
}

.lyrics-debug-toggle {
  position: fixed;
  bottom: 10px;
  right: 10px;
  background: rgba(0, 0, 0, 0.5);
  color: white;
  border: none;
  padding: 5px 10px;
  border-radius: 5px;
  cursor: pointer;
  z-index: 1000;
}

/* 添加歌词模式的样式 */
.visualizer-container.lyrics-mode {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.lyrics-layout {
  display: flex;
  width: 90%;
  max-width: 1200px;
  height: 80vh;
  margin: 0 auto;
  padding: 20px;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 15px;
  backdrop-filter: blur(10px);
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.7);
  overflow: hidden;
}

.lyrics-layout-left {
  width: 230px;
  padding-right: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
}

.lyrics-layout-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-left: 20px;
  overflow: hidden;
}

.lyrics-track-info {
  text-align: left;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.lyrics-track-info .track-title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lyrics-track-info .track-prefix,
.lyrics-track-info .track-artist {
  font-size: 14px;
  opacity: 0.8;
  margin-bottom: 5px;
}

.cover-container-lyrics {
  position: relative;
  width: 180px;
  height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.1s ease-out;
  cursor: pointer;
}

.cover-container-lyrics .progress-ring {
  position: absolute;
  top: 0;
  left: 0;
  width: 180px;
  height: 180px;
  z-index: 1;
}

.cover-container-lyrics .visualizer-image {
  width: 160px;
  height: 160px;
  position: absolute;
  z-index: 2;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
}

.lyrics-container-integrated {
  flex: 1;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
  padding: 10px 0;
  height: calc(100% - 80px); /* 留出标题区域空间 */
  position: relative; /* 确保定位上下文正确 */
  scroll-behavior: auto; /* 允许即时滚动 */
}

.lyrics-container-integrated::-webkit-scrollbar {
  width: 5px;
}

.lyrics-container-integrated::-webkit-scrollbar-track {
  background: transparent; 
}

.lyrics-container-integrated::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.3);
  border-radius: 10px;
}

.lyrics-container-integrated .lyrics-wrapper {
  width: 100%;
  overflow-y: visible;
}

.lyrics-container-integrated .lyrics-content {
  text-align: center;
  padding: 10px 0;
  position: relative;
  width: 100%;
  min-height: 100%; /* 确保内容有足够高度可滚动 */
}

.lyrics-content::before,
.lyrics-content::after {
  content: '';
  display: block;
  height: 40vh; /* 上下各添加视口高度的40%作为填充 */
  width: 100%;
}

.lyric-line {
  padding: 8px 0;
  transition: all 0.3s ease;
  opacity: 0.6;
  font-size: 14px;
  line-height: 1.5;
  width: 100%;
  display: block;
}

.lyric-line.active {
  opacity: 1;
  font-size: 18px;
  font-weight: bold;
  color: #1db954; /* Spotify绿色 */
  text-shadow: 0 0 5px rgba(29, 185, 84, 0.5);
  padding: 10px 0;
}

.standard-layout {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
}

/* 添加模式切换过渡动画 */
.fade-enter-active,
.fade-leave-active,
.mode-fade-enter-active,
.mode-fade-leave-active,
.mode-slide-enter-active,
.mode-slide-leave-active {
  transition: all 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.mode-fade-enter-from,
.mode-fade-leave-to {
  opacity: 0;
  transform: scale(0.95);
}

.mode-slide-enter-from {
  opacity: 0;
  transform: translateY(30px);
}

.mode-slide-leave-to {
  opacity: 0;
  transform: translateY(-30px);
}

/* 添加歌词模式的样式 */
.visualizer-container.lyrics-mode {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.lyrics-layout {
  display: flex;
  width: 90%;
  max-width: 1200px;
  height: 80vh;
  margin: 0 auto;
  padding: 20px;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 15px;
  backdrop-filter: blur(10px);
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.7);
  overflow: hidden;
  transition: all 0.5s ease;
}

.lyrics-layout-left {
  width: 230px;
  padding-right: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.5s ease;
}

.lyrics-layout-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding-left: 20px;
  overflow: hidden;
  transition: all 0.3s ease;
}

.lyrics-track-info {
  text-align: left;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.3s ease;
}

.lyrics-track-info .track-title {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.3s ease;
}

.lyrics-track-info .track-prefix,
.lyrics-track-info .track-artist {
  font-size: 14px;
  opacity: 0.8;
  margin-bottom: 5px;
  transition: color 0.3s ease;
}

.cover-container-lyrics {
  position: relative;
  width: 180px;
  height: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.1s ease-out;
  cursor: pointer;
}

.cover-container-lyrics .progress-ring {
  position: absolute;
  top: 0;
  left: 0;
  width: 180px;
  height: 180px;
  z-index: 1;
}

.cover-container-lyrics .visualizer-image {
  width: 160px;
  height: 160px;
  position: absolute;
  z-index: 2;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
}

.lyrics-container-integrated {
  flex: 1;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
  padding: 10px 0;
  transition: all 0.3s ease;
}

.lyrics-container-integrated::-webkit-scrollbar {
  width: 5px;
}

.lyrics-container-integrated::-webkit-scrollbar-track {
  background: transparent; 
}

.lyrics-container-integrated::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.3);
  border-radius: 10px;
}

.lyrics-container-integrated .lyrics-wrapper {
  max-height: none;
}

.standard-layout {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  width: 100%;
  transition: all 0.5s ease;
}

.track-title {
  transition: color 0.3s ease;
}

.track-prefix, .track-artist {
  transition: color 0.3s ease;
}

.lyric-line {
  transition: all 0.3s ease;
}

.lyric-line.active {
  transition: all 0.3s ease;
}
</style> 